题目:用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. 获取设备上全部系统app信息

    在获取android设备的全部程序信息一文中介绍了获取手机上全部app信息的方法,以下介绍过滤掉系统app的方法: MainActivity: package com.home.getsysapp; ...

  2. phonegap 安装和使用eclipse

    1.下载nodejs...然后注销让nodejs可用 2.下载jdk,ant.和安卓的sdk. jdk是为ant编译时需要,设置JAVA_HOME环境变量 C:\Program Files\Java\ ...

  3. Dijkstra最短路径算法[贪心]

    Dijkstra算法的标记和结构与prim算法的用法十分相似.它们两者都会从余下顶点的优先队列中选择下一个顶点来构造一颗扩展树.但千万不要把它们混淆了.它们解决的是不同的问题,因此,所操作的优先级也是 ...

  4. 怎样用通用pe工具箱制作U盘启动盘

    U盘启动盘制作过程,随着网络的普及,电脑已经成为我们日常生活中的重要一环,最近自己重装了下电脑系统,无意中发现一个傻瓜式的U盘装系统方法,就把怎么制作通用pe工具箱u盘启动盘的经验拿出来跟大家分享下. ...

  5. 判断手机andriod还是iphone

    手机识别:var isAndroid = navigator.appVersion.toLowerCase().indexOf(‘android’) >= 0,isIphone = naviga ...

  6. mysql 批量插入数据过多的解决方法

    使用场景: 测试时需要插入100w的数据,跑sql脚本插入非常慢. 存储过程如下: //DELIMITER DROP PROCEDURE if EXISTS createAmountCount; cr ...

  7. XML 之 与Json或String的相互转换

    1.XML与String的相互转换 [1] XML 转为 String //载入Xml文件 XmlDocument xdoc = new XmlDocument(); xdoc.Load(" ...

  8. B. Fox And Two Dots

    B. Fox And Two Dots time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  9. E - 最短的名字

    Description 在一个奇怪的村子中,很多人的名字都很长,比如aaaaa, bbb and abababab. 名字这么长,叫全名显然起来很不方便.所以村民之间一般只叫名字的前缀.比如叫'aaa ...

  10. Java垃圾回收(GC)与引用的种类

    垃圾回收 GC public class MyObject {     private String id;     public MyObject(String id) {         this ...