题目:用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)

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

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

 /* 用setvbuf来实现setbuf */
#include <stdio.h>
#include <stdlib.h> void pr_stdio(const char *, FILE *);
void my_setbuf(FILE *, char *); int main(void)
{
char buf[BUFSIZ];
char filename[BUFSIZ];
FILE *fp; printf("Please input a filename:");
scanf(" %s", filename); if ((fp = fopen(filename, "r")) == NULL) /* 打开文件 */
{
printf("fopen error");
exit();
} pr_stdio(filename, fp); /* 查看是什么缓冲,一般是全缓冲 */ if (fp->_IO_file_flags &_IO_UNBUFFERED ) /* 文件流是无缓冲的,调成有缓冲 */
my_setbuf(fp, buf);
else /* 文件流是有缓冲的,调成无缓冲 */
my_setbuf(fp, NULL); printf("After setbuf...\n");
pr_stdio(filename, fp); /* 关闭了缓冲 */ return ;
} void pr_stdio(const char *pathname, FILE *fp)
{
printf("stream = %s, ", pathname); if (fp->_IO_file_flags & _IO_UNBUFFERED) /* 无缓冲 */
printf("unbuffered\n");
else if (fp->_IO_file_flags & _IO_LINE_BUF) /* 行缓冲 */
printf("line buffered\n");
else /* 全缓冲 */
printf("fully buffered\n");
} void my_setbuf(FILE *fp, char *buf) /* setbuf函数,要么打开,要么关闭,是全缓冲还是行缓冲决定于fp */
{
int fd; fd = fileno(fp); /* 获取文件描述符 */ if (buf == NULL) /* 修改为无缓冲 */
{
setvbuf(fp, buf, _IONBF, BUFSIZ);
return;
} if (fd == || fd == || fd == ) /* 与终端设备相关,应设为行缓冲 */
setvbuf(fp, buf, _IOLBF, BUFSIZ);
else /* 设为全缓冲 */
setvbuf(fp, buf, _IOFBF, BUFSIZ); }

结果如下:

《APUE》第五章练习1的更多相关文章

  1. APUE第五章:标准IO库

    5.2流和file对象 #include <wchar.h> int fwide(FILE *fp, int mode); Returns: positive if stream is w ...

  2. 《APUE》第五章笔记

    第五章具体介绍了标准I/O库的各种细节,要是一一列出来,有费精力且可能列不全,故只讲平常多用到的.标准输入输出是由一大批函数组成的. 要记住,标准输入输出是有缓冲的,就是当缓冲区的数据满了的时候,才会 ...

  3. UNP学习笔记(第十五章 UNIX域协议)

    UNIX域协议是在单个主机上执行客户/服务器通信的一种方法 使用UNIX域套接字有以下3个理由: 1.UNIX域套接字往往比通信两端位于同一个主机的TCP套接字快出一倍 2.UNIX域套接字可用于在同 ...

  4. 《Django By Example》第五章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者@ucag注:大家好,我是新来的翻译, ...

  5. 《Entity Framework 6 Recipes》中文翻译系列 (22) -----第五章 加载实体和导航属性之延迟加载

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第五章 加载实体和导航属性 实体框架提供了非常棒的建模环境,它允许开发人员可视化地使 ...

  6. 精通Web Analytics 2.0 (7) 第五章:荣耀之钥:度量成功

    精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第五章:荣耀之钥:度量成功 我们的分析师常常得不到我们应得的喜欢,尊重和资金,因为我们没有充分地衡量一个黄金概念:成果.因为我们 ...

  7. 《Linux内核设计与实现》读书笔记 第五章 系统调用

    第五章系统调用 系统调用是用户进程与内核进行交互的接口.为了保护系统稳定可靠,避免应用程序恣意忘形. 5.1与内核通信 系统调用在用户空间进程和硬件设备间添加了一个中间层, 作用:为用户空间提供了一种 ...

  8. Java语言程序设计(基础篇) 第五章 循环

    第五章 循环 5.2 while循环 1.while循环的语法如下: while(循环继续条件){ //循环体 语句(组); } 2.程序:提示用户为两个个位数相加的问题给出答案 package co ...

  9. 读《编写可维护的JavaScript》第五章总结

    第五章 UI层的松耦合 5.1 什么是松耦合 在Web开发中,用户界面是由三个彼此隔离又相互作用的层定义的: HTML是用来定义页面的数据和语义 CSS用来给页面添加样式 JavaScript用来给页 ...

  10. 《Linux内核设计与实现》课本第五章学习笔记——20135203齐岳

    <Linux内核设计与实现>课本第五章学习笔记 By20135203齐岳 与内核通信 用户空间进程和硬件设备之间通过系统调用来交互,其主要作用有三个. 为用户空间提供了硬件的抽象接口. 保 ...

随机推荐

  1. [Bower] Bower

    //search bower search jquery bower search jquery | grep formstyler //info bower info jquery //instal ...

  2. Ruby on Rails Tutorial 第四章 Rails背后的Ruby 之 其他数据类型(二)

    1.方法 定义如下所示: def string_message(str='') if str.empty? "It's an empty string!" else "T ...

  3. Java_Spring MVC_Servlet

    Spring MVC 例子 http://www.cnblogs.com/liukemng/p/3724379.html 详解: http://jinnianshilongnian.iteye.com ...

  4. subline的安装

    简单的安装方法 使用Ctrl+`快捷键或者通过View->Show Console菜单打开命令行,粘贴如下代码: import urllib.request,os; pf = 'Package ...

  5. B - Broken Keyboard (a.k.a. Beiju Text)

    Problem B Broken Keyboard (a.k.a. Beiju Text) You're typing a long text with a broken keyboard. Well ...

  6. 沈逸老师ubuntu速学笔记(2)-- ubuntu16.04下 apache2.4和php7结合编译安装,并安裝PDOmysql扩展

    1.编译安装apache2.4.20 第一步: ./configure --prefix=/usr/local/httpd --enable-so 第二步: make 第三步: sudo make i ...

  7. 求可能组合VB源码代写

    输入1-20的整数n,把从1到n的n个整数摆成一个环,使得该环上任意相邻的两个数之和为素数.求出所有可能组合. 专业程序代写c++程序代写

  8. [Android]应用的前后台运行

    在开发中,你是不是没有抽象一个出常用的类,那你可能要为你的懒惰付出很大的代价.要时刻记得自己的工具箱,不断往里面添加一些小小玩意.今天就给大家带来一个很有意思的例子.前后台运行!! 在Android开 ...

  9. Tire树

    Trie树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种. 典型应用是用于统计和排序大量的字符串(但不仅限于字符串), 所以经常被搜索引擎系统用于文本词频统计. 字典树(Trie)可以保存 ...

  10. hdu 4455 动态规划

    思路:用sum[i]表示区间长度为i的不相同数的个数和,假使所有的数都不相同,那么sum[i]=sum[i-1]+n-i+1-later[i-1]; later[i-1]表示的是序列最后面的长度为i- ...