c语言中用来指示文件缓冲区中具体读写位置,C语言文件读写操作中缓冲区问题和setbuf函数详解...
清除和设置文件缓冲区
(1).清除文件缓冲区函数:
int fflush(FILE *stream); int flushall();
fflush()函数将清除由stream指向的文件缓冲区里的内容,常用于写完一些数据后,立即用该函数清除缓冲区,以免误操作时,破坏原来的数据。
flushall()将清除所有打开文件所对应的文件缓冲区。
(2).设置文件缓冲区函数
void setbuf(FILE *stream,char *buf); void setvbuf(FILE *stream,char
*buf,int type,unsigned size);
这两个函数将使得打开文件后,用户可建立自己的文件缓冲区,而不使用fopen()函数打开文件设定的默认缓冲区。
对于setbuf()函数,buf指出的缓冲区长度由头文件stdio.h中定义的宏BUFSIZE的值决定,缺省值为512字节。当选定buf为空时,setbuf函数将使的文件I/O不带缓冲。而对setvbuf函数,则由malloc函数来分配缓冲区。参数size指明了缓冲区的长度(必须大于0),而参数type则表示了缓冲的类型,其值可以取如下值:
type 值 含义 _IOFBF 文件全部缓冲,即缓冲区装满后,才能对文件读写 _IOLBF
文件行缓冲,即缓冲区接收到一个换行符时,才能对文件读写 _IONBF
文件不缓冲,此时忽略buf,size的值,直接读写文件,不再经过文件缓冲区缓冲
文件的随机读写函数
前面介绍的文件的字符/字符串读写,均是进行文件的顺序读写,即总是从文件的开头开始进行读写。这显然不能满足我们的要求,C语言提供了移动文件指针和随机读写的函数,它们是:
(1).移动文件指针函数:long
ftell(FILE *stream); int rewind(FILE *stream); fseek(FILE
*stream,long offset,int origin);
函数ftell()用来得到文件指针离文件开头的偏移量。当返回值是-1时表示出错。rewind()函数用于文件指针移到文件的开头,当移动成功时,返回0,否则返回一个非0值。fseek()函数用于把文件指针以origin为起点移动offset个字节,其中origin指出的位置可有以下几种:
origin 数值 代表的具体位置 SEEK_SET 0 文件开头 SEEK_CUR 1 文件指针当前位置 SEEK_END 2
文件尾 例如: fseek(fp,10L,0);
把文件指针从文件开头移到第10字节处,由于offset参数要求是长整型数,故其数后带L。 fseek(fp,-15L,2);
把文件指针从文件尾向前移动15字节。
(2).文件随机读写函数int
fread(void *ptr,int size,int nitems,FILE *stream); int fwrite(void
*ptr,int size,int nitems,FILE *stream);
fread()函数从流指针指定的文件中读取nitems个数据项,每个数据项的长度为size个字节,读取的nitems数据项存入由ptr指针指向的内存缓冲区中,在执行fread()函数时,文件指针随着读取的字节数而向后移动,最后移动结束的位置等于实际读出的字节数。该函数执行结束后,将返回实际读出的数据项数,这个数据项数不一定等于设置的nitems,因为若文件中没有足够的数据项,或读中间出错,都会导致返回的数据项数少于设置的nitems。当返回数不等于nitems时,可以用feof()或ferror()函数进行检查。
fwrite()函数从ptr指向的缓冲区中取出长度为size字节的nitems个数据项,写入到流指针stream指向的文件中,执行该操作后,文件指针将向后移动,移动的字节数等于写入文件的字节数目。该函数操作完成后,也将返回写入的数据项数。
setbuf函数 详解
程序输出有两种方式:一种是即时处理方式,另一种是先暂存起来,然后再大块写入的方式,前者往往造成较高的系统负担。因此,c语言实现通常都允许程序员进行实际的写操作之前控制产生的输出数据量。
这种控制能力一般是通过库函数setbuf实现的。如果buf是一个大小适当的字符数组,那么:
setbuf(stdout,buf);
语句将通知输入/输出库,所有写入到stdout的输出都应该使用buf作为输出缓冲区,直到buf缓冲区被填满或者程序员直接调用fflush(译注:对于由写操作打开的文件,调用fflush将导致输出缓冲区的内容被实际地写入该文件),buf缓冲区中的内容才实际写入到stdout中。缓冲区的大小由系统头文件中的BUFSIZ定义。
下面的程序的作用是把标准输入的内容复制到标准输出中,演示了setbuf库函数最显而易见的用法:
#include
main()
{
int c;
char buf[BUFSIZ];
setbuf(stdout, buf);
while((c=getchar())!=EOF)
putchar(c);
}
遗憾的是,这个程序是错误的,仅仅是因为一个细微的原因。程序中对库函数setbuf的调用,通知了输入/输出库所有字符的标准输出应该首先缓存在buf中。要找到问题出自何处,我们不妨思考一下buf缓冲区最后一次被清空是在什么时候?答案是在main函数结束之后,作为程序交回控制给操作系统之前C运行时库所必须进行的清理工作的一部分。但是,在此之前buf字符数组已经被释放!
要避免这种类型的错误有两种办法。第一种办法是让缓冲数组成为静态数组,既可以直接显式声明buf为静态:
static char buf[BUFSIZ];
也可以把buf声明完全移到main函数之外。第二种办法是动态分配缓冲区,在程序中并不主动释放分配的缓冲区(译注:山于缓冲区是动态分配的,所以main函数结束时并不会释放该缓冲区,这样C运行时库进行清理工作时就不会发生缓冲区已释放的情况):
char *malloc();
setbuf(stdout,malloc(BUFSIZ));
如果读者关心一些编程“小技巧”,也许会注意到这里其实并不需要检查malloc函数调用是否成功。如果malloc函数调用失败,将返回一个null指针。setbuf函数的第二个参数取值可以为null,此时标准输出不需要进行缓冲。这种情况下,程序仍然能够工作,只不过速度较慢而已。
c语言中用来指示文件缓冲区中具体读写位置,C语言文件读写操作中缓冲区问题和setbuf函数详解...相关推荐
- c++ memset 语言_C/C++ 中memset() 函数详解及其作用介绍
memset 函数是内存赋值函数,用来给某一块内存空间进行赋值的: 包含在头文件中,可以用它对一片内存空间逐字节进行初始化: 原型为 : void *memset(void *s, int v, si ...
- java的匿名函数_JAVA语言中的匿名函数详解
本文主要向大家介绍了JAVA语言中的匿名函数详解,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. 一.使用匿名内部类 匿名内部类由于没有名字,所以它的创建方式有点儿奇怪.创建格式如下: ...
- c语言中快排函数,c语言快排函数详解
c语言快排函数详解 int cmp(const void *a, const void *b) 返回正数就是说 cmp 传入参数第一个要放在第二个后面, 负数就是传入参数第一个要放第二个前面, 如果是 ...
- html设置选择多个文件,选取多个连续文件或文件夹 怎样在文件夹中一次选中多个文件?...
在Windows资源管理器中,选定多个连续文件的操作为 (A) 按住Shift键,单击每一个要选定的文件名 (B) 按住Alt键,单击每一个ctrl键.一,选定单个文件或文件夹:单击该文件或文件夹.二 ...
- 【解决方法】因为 'PRIMARY' 文件组已满。请删除不需要的文件、删除文件组中的对象、将其他文件添加到文件组或为文件组中的现有文件启用自动增长,以便增加可用磁盘空间
文章目录 平台 问题描述 解决问题 1.查看数据库数据文件存放路径 2.查看存放路径的盘是否已满 3.更改数据库设置 平台 sqlserver 2012 问题描述 正常运行的生产系统,今天下午突然发现 ...
- python中文件读写--open函数详解
python中open函数详解 在python中文件的读取分为三步走: 读:打开文件 -> 读文件 -> 关闭文件 (有点像把大象放进冰箱需要几步?的问题) 1.open函数 open函数 ...
- gets和fgets函数及其区别,C语言gets和fgets函数详解
gets和fgets函数及其区别,C语言gets和fgets函数详解 每当讨论 gets 函数时,大家不由自主地就会想起 1988 年的"互联网蠕虫",它在 UNIX 操作系统的 ...
- scanf函数详解与缓冲区
1.基本信息 函数原型: int scanf( char *format, args, ...); 函数返回值: 读入并赋给args的数据个数,遇到文件结束返回EOF,出错返回0. 函数功能: sca ...
- 内核中的kmalloc函数详解
一.kmalloc函数详解 #include <linux/slab.h> void *kmalloc(size_t size, int flags); 给 kmalloc 的第一个参数是 ...
最新文章
- mysql 5.7 gtid 主从_MySQL 5.7基于GTID的主从复制实践
- Android学习之JSON数据解析
- 域用户的登录过程和GC的关系
- sql 自动增加排序 并且初始值是000001
- 颈椎前路caspar撑开器_“骨质增生”导致的颈椎病怎么破?
- 腾讯视频与中国电信签署战略合作协议 共同成立5G联合实验室
- pnpm 是更快的包管理工具
- 转-TabHost组件(二)(实现底部菜单导航)
- Tk-Mybatis(通用mybatis)简单使用
- Java的中文转换拼音、五笔简码
- Scratch 游戏项目学习法 —— 接苹果(八)添加接住苹果的接盘(角色)
- Linux基础与部署
- 【蓝桥杯省赛】冲刺练习题【第十二届省赛2套题】倒计时【02】天(准考证组委会已下发,请查询)
- iOS 气泡聊天效果
- 【BATJ面试必会】JAVA面试到底需要掌握什么?【下】
- 会计学(非专业)第7章 固定资产
- 成本与体验的“非零和博弈”
- cocos-lua中播放音乐音效
- DDR2 IP核地址总线解疑
- arch Linux安装至U盘(兼容UEFI和BIOS启动)
热门文章
- 如何利用BibTex生成论文参考文献列表
- 身份证识别,银行卡识别,驾驶证识别,行驶证识别,根据百度文字识别 api 封装,能快速识别身份证信息,银行卡信息,驾驶证信息,行驶证信息,使用非常方便
- linux获取交换机端口信息,基于Linux的端口状态实时检测方法、电路和交换机与流程...
- NVIDIA Jestion Xavier联网
- 深度学习---反向传播算法BP
- android开发工具箱专业版,安卓工具箱专业版下载-安卓工具箱专业版(Android Toolbox Pro) 安卓版v1.2.1-pc6手机下载...
- java 中文繁简体转换工具 opencc4j 使用介绍 1.8.0
- 【20考研】单词记不住?速效记忆法解决问题
- 跑动大数据的笔记本配置_大数据告诉你,最完美的跑步姿势就是你这样的!
- jave Duration: N/A, bitrate: N/A