• 《APUE》第五章练习1


    题目:用setvbuf实现setbuf。

    这两个函数都是改变流的缓冲模式的。函数原型如下:

    #include <stdio.h>

    void setbuf(FILE *fp, char *buf);

    void setvbuf(FILE *fp, char *buf, int mode, size_t size);

    毫无疑问,setvbuf是setbuf的升级版。下面我们再看看这两个函数是怎么工作的:

    setbuf只能决定打开或者关闭缓冲(设buf为NULL则关闭),而是行缓冲还是全缓冲则决定与fp是否与终端设备相关。

    setvbuf则更加详细,可以自由选择缓冲类型而缓冲区的大小(图上合适长度的系统缓冲区则就是本身就有定义的BUFSIZ)

    要注意的是:使用这两个函数应该是在打开流之后和使用流之前。

    下面给出我实现的代码,看了之后应该也很容易理解:

     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...
    ");
    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
    ");
    42     else if (fp->_IO_file_flags & _IO_LINE_BUF)    /* 行缓冲 */
    43         printf("line buffered
    ");
    44     else                        /* 全缓冲 */
    45         printf("fully buffered
    ");
    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 }
    View Code

    结果如下:

  • 相关阅读:
    【C++ 学习笔记】 Vector
    【AWS】 AWS Free Usage Tier
    【C++ 学习笔记】 MFC CEdit
    【MySql】MySql安装和ODBC设置
    【C++ 学习笔记】 变量转换
    【Perl学习笔记】列表和数组
    【C++ 学习笔记】 值传递
    【Java 学习笔记】 MyEclipse各种细节
    【NLP】 向量空间模型
    【Linux】 Cygwin操作总结
  • 原文地址:https://www.cnblogs.com/fusae-blog/p/4274621.html
Copyright © 2020-2023  润新知