Chapter 5 Exercise 1 and Chapter 5 exercise
Question: Use setvbuf to implement setbuf
Both functions change the stream buffer mode. The function prototype is as follows:
# Include <stdio. h>
Void setbuf (FILE * fp, char * buf );
Void setvbuf (FILE * fp, char * buf, int mode, size_t size );
There is no doubt that setvbuf is an upgraded version of setbuf. Let's take a look at how these two functions work:
Setbuf can only determine whether to enable or disable the buffer (if the buf is set to NULL, It is disabled), but whether the row buffer or full buffer determines whether the fp is related to the terminal device.
Setvbuf is more detailed. You can freely select the buffer type and the buffer size (the system buffer with the proper length on the figure is the defined BUFSIZ)
Note that the two functions should be used after opening the stream and before using the stream.
The code I implemented is provided below, which should be easy to understand after reading:
1/* use setvbuf to implement setbuf */2 # include <stdio. h> 3 # include <stdlib. h> 4 5 void pr_stdio (const char *, FILE *); 6 void my_setbuf (FILE *, char *); 7 8 int main (void) 9 {10 char buf [BUFSIZ]; 11 char filename [BUFSIZ]; 12 FILE * fp; 13 14 printf ("Please input a filename :"); 15 scanf ("% s", filename); 16 17 if (fp = fopen (filename, "r") = NULL) /* open the file */18 {19 printf ("fopen error"); 20 exit (1); 21} 22 23 pr_stdio (filename, fp ); /* check what the buffer is. Generally, the full buffer */24 25 if (fp-> _ IO_file_flags & _ IO_UNBUFFERED)/* file streams are not buffered, it is converted to buffer */26 my_setbuf (fp, buf); 27 else/* file streams are buffered, and converted to no buffer */28 my_setbuf (fp, NULL ); 29 30 printf ("After setbuf... \ n "); 31 pr_stdio (filename, fp);/* disabled buffer */32 33 return 0; 34} 35 36 void pr_stdio (const char * pathname, FILE * fp) 37 {38 printf ("stream = % s,", pathname); 39 40 if (fp-> _ IO_file_flags & _ IO_UNBUFFERED) /* No buffer */41 printf ("unbuffered \ n"); 42 else if (fp-> _ IO_file_flags & _ IO_LINE_BUF) /* row buffer */43 printf ("line buffered \ n"); 44 else/* Full buffer */45 printf ("fully buffered \ n "); 46} 47 48 void my_setbuf (FILE * fp, char * buf)/* setbuf function, either open or close, whether full or row buffering is determined by fp */49 {50 int fd; 51 52 fd = fileno (fp ); /* get the file descriptor */53 54 if (buf = NULL)/* change it to unbuffered */55 {56 setvbuf (fp, buf, _ IONBF, BUFSIZ ); 57 return; 58} 59 60 if (fd = 0 | fd = 1 | fd = 2)/* Related to the terminal device, set row buffering */61 setvbuf (fp, buf, _ IOLBF, BUFSIZ); 62 else/* to full buffering */63 setvbuf (fp, buf, _ IOFBF, BUFSIZ); 64 65}View Code
The result is as follows: