EOF是什么?(笔记)
一、参考文章
二、知识点
1、EOF 定义在 /usr/include/stdio.h 文件中:
从上面 EOF
的定义我们可以看出 EOF 本质上就是一个值为-1
的常量!
2、在Linux系统之中,EOF根本不是一个字符,而是当系统读取到文件结尾,所返回的一个信号值(也就是-1)。至于系统怎么知道文件的结尾,资料上说是通过比较文件的长度。
3、fgetc()不仅是遇到文件结尾时返回EOF,而且当发生错误时,也会返回EOF。因此,C语言又提供了feof()函数,用来保证确实是到了文件结尾
改进前:
1 int c; 2 3 while (!feof(fp)) { 4 5 c = fgetc(fp); 6 7 do something; 8 9 }
改进后:
1 int c = fgetc(fp); 2 3 while (c != EOF) { 4 5 do something; 6 7 c = fgetc(fp); 8 9 } 10 11 if (feof(fp)) { 12 13 printf("\n End of file reached."); 14 15 } else { 16 17 printf("\n Something went wrong."); 18 19 }
4、对于普通文本文件
对于这种文件,Linux 系统判断普通文本文件是否读取到文件末尾的方法是:read 函数会对所打开的文件维护一个读取指针,然后根据这个指针跟文件开始位置的指针值相减得到一个相对于文件开始位置的偏移字节数,最后通过这样一个偏移字节数和文件本身的大小进行一个比较,如果相对于文件开始位置的偏移字节数大于文件本身的大小,那么就返回一个 EOF 常量,说明此时已经读取到文件末尾了。
5、对于标准输入文件
inux 系统判断标准输入文件是否读取到文件末尾的方法是:设置一个特殊的输入标记来表示文件末尾,而在Linux 系统中这个标记就是组合键Ctrl+D
,当系统捕获到这个组合键时,就让 r read 函数返回一个 EOF 常量,告知程序已经读取到标准文件的末尾了。
6、对于socket文件
如果服务端进程关闭了socket连接,那么客户端会接收到服务端发送过来的一个 TCP 协议的 FIN 数据包,然后客户端进程中原本阻塞着等待接收服务端进程数据的 read函数此时就会被唤醒,返回一个值 0。这跟我们前面提到两种文件读到文件末尾返回 EOF(值为-1)的情况有点差别,所以在程序中从 socket 进行读取操作时,判断数据流结束的标志不是 -1 而是 0。
7、一定要记住这样一个概念:EOF 是一个常量而不是一个字符!。