題目:用setvbuf實現setbuf。ide
這兩個函數都是改變流的緩衝模式的。函數原型以下:函數
#include <stdio.h>spa
void setbuf(FILE *fp, char *buf);code
void setvbuf(FILE *fp, char *buf, int mode, size_t size);blog
毫無疑問,setvbuf是setbuf的升級版。下面咱們再看看這兩個函數是怎麼工做的:input
setbuf只能決定打開或者關閉緩衝(設buf爲NULL則關閉),而是行緩衝仍是全緩衝則決定與fp是否與終端設備相關。原型
setvbuf則更加詳細,能夠自由選擇緩衝類型而緩衝區的大小(圖上合適長度的系統緩衝區則就是自己就有定義的BUFSIZ)it
要注意的是:使用這兩個函數應該是在打開流以後和使用流以前。io
下面給出我實現的代碼,看了以後應該也很容易理解:event
1 /* 用setvbuf來實現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) /* 打開文件 */ 18 { 19 printf("fopen error"); 20 exit(1); 21 } 22 23 pr_stdio(filename, fp); /* 查看是什麼緩衝,通常是全緩衝 */ 24 25 if (fp->_IO_file_flags &_IO_UNBUFFERED ) /* 文件流是無緩衝的,調成有緩衝 */ 26 my_setbuf(fp, buf); 27 else /* 文件流是有緩衝的,調成無緩衝 */ 28 my_setbuf(fp, NULL); 29 30 printf("After setbuf...\n"); 31 pr_stdio(filename, fp); /* 關閉了緩衝 */ 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) /* 無緩衝 */ 41 printf("unbuffered\n"); 42 else if (fp->_IO_file_flags & _IO_LINE_BUF) /* 行緩衝 */ 43 printf("line buffered\n"); 44 else /* 全緩衝 */ 45 printf("fully buffered\n"); 46 } 47 48 void my_setbuf(FILE *fp, char *buf) /* setbuf函數,要麼打開,要麼關閉,是全緩衝仍是行緩衝決定於fp */ 49 { 50 int fd; 51 52 fd = fileno(fp); /* 獲取文件描述符 */ 53 54 if (buf == NULL) /* 修改成無緩衝 */ 55 { 56 setvbuf(fp, buf, _IONBF, BUFSIZ); 57 return; 58 } 59 60 if (fd == 0 || fd == 1 || fd == 2) /* 與終端設備相關,應設爲行緩衝 */ 61 setvbuf(fp, buf, _IOLBF, BUFSIZ); 62 else /* 設爲全緩衝 */ 63 setvbuf(fp, buf, _IOFBF, BUFSIZ); 64 65 }
結果以下: