C语言FILE结构体以及缓冲区深入探讨(unix/linux编程实现2.4)
来源:互联网 发布:大学生抑郁症数据 编辑:程序博客网 时间:2024/05/17 18:47
在C语言中,用一个指针变量指向一个文件,这个指针称为文件指针。通过文件指针就可对它所指的文件进行各种操作。
看吧,我们经常使用的 NULL、EOF、feof()、getc() 等都是 stdio.h 中定义的宏。
定义文件指针的一般形式为:
FILE *fp;
这里的FILE,实际上是在stdio.h中定义的一个结构体,该结构体中含有文件名、文件状态和文件当前位置等信息。我们通过fopen返回一个文件指针(指向FILE结构体的指针)来进行文件操作。
注意:FILE是文件缓冲区的结构,fp也是指向文件缓冲区的指针。
不同编译器 stdio.h 头文件中对 FILE 的定义略有差异,这里以标准C举例说明:
- #define NULL0
- #defineEOF (-1)
- #define BUFSIZ1024
- #define OPEN_MAX20 // 一次打开的最大文件数
- // 定义FILE结构体
- typedefstruct _iobuf {
- int cnt;// 剩余的字符,如果是输入缓冲区,那么就表示缓冲区中还有多少个字符未被读取
- char*ptr;// 下一个要被读取的字符的地址
- char*base;// 缓冲区基地址
- int flag;// 读写状态标志位
- int fd;// 文件描述符
- } FILE;
- extern FILE _iob[OPEN_MAX];
- #definestdin (&_iob[0])// stdin 的文件描述符为0
- #definestdout (&_iob[1])// stdout 的文件描述符为1
- #definestderr (&_iob[2])// stdout 的文件描述符为2
- enum _flags{
- _READ =01,// 读文件
- _WRITE=02,// 写文件
- _UNBUF=04,// 无缓冲
- _EOF = 010,// 文件结尾EOF
- _ERR = 020 // 出错
- };
- int_fillbuf(FILE*); // 函数声明,填充缓冲区
- int_flushbuf(int, FILE*); // 函数声明,刷新缓冲区
- #definefeof(p)((p)->flag& _EOF)!= 0)
- #defineferror(p)((p)->flag& _ERR)!= 0)
- #definefileno(p)((p)->fd)
- #definegetc(p)(--(p)->cnt>= 0\
- ?(unsignedchar)*(p)->ptr++: _fillbuf(p))
- #defineputc(x,p)(--(p)->cnt>= 0\
- ?*(p)->ptr++= (x): _flushbuf((x),p))
- #definegetchar()getc(stdin)
- #defineputcher(x)putc ((x), stdout)
注意:一个长的 #define 语句可以用反斜杠(\)分成多行。
下面说一下如果控制缓冲区。
我们知道,当我们从键盘输入数据的时候,数据并不是直接被我们得到,而是放在了缓冲区中,然后我们从缓冲区中得到我们想要的数据 。如果我们通过setbuf()或setvbuf()函数将缓冲区设置10个字节的大小,而我们从键盘输入了20个字节大小的数据,这样我们输入的前10个数据会放在缓冲区中,因为我们设置的缓冲区的大小只能够装下10个字节大小的数据,装不下20个字节大小的数据。那么剩下的那10个字节大小的数据怎么办呢?暂时放在了输入流中。请看下图:
上面的箭头表示的区域就相当是一个输入流,红色的地方相当于一个开关,这个开关可以控制往深绿色区域(标注的是缓冲区)里放进去的数据,输入20个字节的数据只往缓冲区中放进去了10个字节,剩下的10个字节的数据就被停留在了输入流里!等待下去往缓冲区中放入!接下来系统是如何来控制这个缓冲区呢?
再说一下 FILE 结构体中几个相关成员的含义:
cnt // 剩余的字符,如果是输入缓冲区,那么就表示缓冲区中还有多少个字符未被读取
ptr // 下一个要被读取的字符的地址
base // 缓冲区基地址
在上面我们向缓冲区中放入了10个字节大小的数据,FILE结构体中的 cnt 变为了10 ,说明此时缓冲区中有10个字节大小的数据可以读,同时我们假设缓冲区的基地址也就是 base 是0x00428e60 ,它是不变的 ,而此时 ptr 的值也为0x00428e60 ,表示从0x00428e60这个位置开始读取数据,当我们从缓冲区中读取5个数据的时候,cnt 变为了5 ,表示缓冲区还有5个数据可以读,ptr 则变为了0x0042e865表示下次应该从这个位置开始读取缓冲区中的数据 ,如果接下来我们再读取5个数据的时候,cnt 则变为了0 ,表示缓冲区中已经没有任何数据了,ptr 变为了0x0042869表示下次应该从这个位置开始从缓冲区中读取数据,但是此时缓冲区中已经没有任何数据了,所以要将输入流中的剩下的那10个数据放进来,这样缓冲区中又有了10个数据,此时 cnt 变为了10 ,注意了刚才我们讲到 ptr 的值是0x00428e69 ,而当缓冲区中重新放进来数据的时候这个 ptr 的值变为了0x00428e60 ,这是因为当缓冲区中没有任何数据的时候要将 ptr 这个值进行一下刷新,使其指向缓冲区的基地址也就是0x0042e860这个值!因为下次要从这个位置开始读取数据!
在这里有点需要说明:当我们从键盘输入字符串的时候需要敲一下回车键才能够将这个字符串送入到缓冲区中,那么敲入的这个回车键(\r)会被转换为一个换行符\n,这个换行符\n也会被存储在缓冲区中并且被当成一个字符来计算!比如我们在键盘上敲下了123456这个字符串,然后敲一下回车键(\r)将这个字符串送入了缓冲区中,那么此时缓冲区中的字节个数是7 ,而不是6。
缓冲区的刷新就是将指针 ptr 变为缓冲区的基地址 ,同时 cnt 的值变为0 ,因为缓冲区刷新后里面是没有数据的!
0 0
- C语言FILE结构体以及缓冲区深入探讨(unix/linux编程实现2.4)
- C语言FILE结构体以及缓冲区深入探讨
- 129 C语言FILE结构体以及缓冲区深入探讨
- C语言FILE结构以及缓冲区深入探讨
- C语言深入探讨实战篇之结构体字节对齐(四)
- C语言 FILE结构体
- C语言FILE结构体
- Unix/Linux编程实践教程(1)--实现more命令(C语言)
- C语言编程—清空键盘缓冲区,Linux下完美实现
- linux c FILE结构体
- C语言编程中的缓冲区
- C语言 FILE结构体解释
- C语言中的FILE结构体
- 关于C语言结构体对齐问题的探讨
- 深入探索C语言之结构体(struct)
- C语言深入学习--checklist3:结构体
- C语言拷贝文件函数实现(linux cp [source file] [target file] 命令的实现)
- C语言编程在Xcode中Scanf 输入跳过以及清空键盘缓冲区总结
- 枚举类
- svn 配置
- java浮点类型float精度与Double精度范围实例使用说明
- C++实现线程池
- SGU 109 Magic of David Copperfield II(构造)
- C语言FILE结构体以及缓冲区深入探讨(unix/linux编程实现2.4)
- Android ActionBar完全解析,使用官方推荐的最佳导航栏(下)
- Debian (Jessie 8.0) 的一些升级后的修复工作, virtualbox不能启动。
- 5 个最好的 Android ORM 框架
- oracle入门之 DDL数据定义语句(一)
- JNI和NDK的区别
- Android ActionBar应用实战,高仿微信主界面的设计
- C#线程同步(1)-------轻量级同步Interlock
- 第三周项目-4