《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)
要注意的是:使用这两个函数应该是在打开流之后和使用流之前。
下面给出我实现的代码,看了之后应该也很容易理解:
/* 用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的更多相关文章
- APUE第五章:标准IO库
5.2流和file对象 #include <wchar.h> int fwide(FILE *fp, int mode); Returns: positive if stream is w ...
- 《APUE》第五章笔记
第五章具体介绍了标准I/O库的各种细节,要是一一列出来,有费精力且可能列不全,故只讲平常多用到的.标准输入输出是由一大批函数组成的. 要记住,标准输入输出是有缓冲的,就是当缓冲区的数据满了的时候,才会 ...
- UNP学习笔记(第十五章 UNIX域协议)
UNIX域协议是在单个主机上执行客户/服务器通信的一种方法 使用UNIX域套接字有以下3个理由: 1.UNIX域套接字往往比通信两端位于同一个主机的TCP套接字快出一倍 2.UNIX域套接字可用于在同 ...
- 《Django By Example》第五章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者@ucag注:大家好,我是新来的翻译, ...
- 《Entity Framework 6 Recipes》中文翻译系列 (22) -----第五章 加载实体和导航属性之延迟加载
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第五章 加载实体和导航属性 实体框架提供了非常棒的建模环境,它允许开发人员可视化地使 ...
- 精通Web Analytics 2.0 (7) 第五章:荣耀之钥:度量成功
精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第五章:荣耀之钥:度量成功 我们的分析师常常得不到我们应得的喜欢,尊重和资金,因为我们没有充分地衡量一个黄金概念:成果.因为我们 ...
- 《Linux内核设计与实现》读书笔记 第五章 系统调用
第五章系统调用 系统调用是用户进程与内核进行交互的接口.为了保护系统稳定可靠,避免应用程序恣意忘形. 5.1与内核通信 系统调用在用户空间进程和硬件设备间添加了一个中间层, 作用:为用户空间提供了一种 ...
- Java语言程序设计(基础篇) 第五章 循环
第五章 循环 5.2 while循环 1.while循环的语法如下: while(循环继续条件){ //循环体 语句(组); } 2.程序:提示用户为两个个位数相加的问题给出答案 package co ...
- 读《编写可维护的JavaScript》第五章总结
第五章 UI层的松耦合 5.1 什么是松耦合 在Web开发中,用户界面是由三个彼此隔离又相互作用的层定义的: HTML是用来定义页面的数据和语义 CSS用来给页面添加样式 JavaScript用来给页 ...
- 《Linux内核设计与实现》课本第五章学习笔记——20135203齐岳
<Linux内核设计与实现>课本第五章学习笔记 By20135203齐岳 与内核通信 用户空间进程和硬件设备之间通过系统调用来交互,其主要作用有三个. 为用户空间提供了硬件的抽象接口. 保 ...
随机推荐
- thinkphp分配数组
TestAction.class.php 的edit方法中 $this->assign('list',array('one'=>'a','two'=>'b')); 后,在edit.h ...
- [AngularJS] ui-router: named views
The ui-router library for AngularJS provides the ability to name views within your application. This ...
- onClick,onServerClick,onClientClick
<asp:button id=button1 runat=server test=button1 onclick=button1_onclick/> <input type=butt ...
- 阿里技术嘉年华(ADC2013)总结与感悟
上周末刚参加了ADC2013(2013.7.13-14),我报的是TCon测试论坛和UCAN用户体验设计论坛,因为我目前从事的是测试工作,但是还是想往用户体验(主要是用研)方向发展,所以 ...
- Ruby on Rails Tutorial 第一章 之 Git项目管理
1.安装和设置 (1)git的安装(略) (2)初始化设置 $ git config --global user.name "LihuaSun" $ git config --gl ...
- 利用 Composer 一步一步构建自己的 PHP 框架(一)——基础准备
『Composer 一统天下的时代已经到来!』——白岩松 “一个时代结束了,另一个时代开始了.” Framework Interoperability Group(框架可互用性小组),简称 FIG,成 ...
- 小白日记35:kali渗透测试之Web渗透-手动漏洞挖掘(一)-默认安装引发的漏洞
手动漏洞挖掘 即扫描后,如何对发现的漏洞告警进行验证. #默认安装 流传linux操作系统比windows系统安全的说法,是因为windows系统默认安装后,会开放很多服务和无用的端口,而且未经过严格 ...
- Ubuntu 下安装VNC server
尽管我们在大部分情况下用ssh登录Ubuntu服务器就好了,但是有时候我们的程序需要在图形界面下运行,这时我们就要用到vnc server这个软件了.在Ubuntu下安装vnc server很简单的, ...
- js函数中的几个特点
定义函数有两种方式:函数声明 函数表达式 1.函数声明是这样的: function box(arg0,arg1,arg2){ //函数体} 关于函数声明有一个重要的特征:函数声明提升,也就是说执行代码 ...
- Ajax--跨域访问的三种方法
一.什么是跨域 我们先回顾一下域名地址的组成: / script/jquery.js http:// (协议号) www (子域名) google (主域名) (端口号) script/jquer ...