EOF到底是什么意思?

简介: 我们在使用C标准I/O时,经常会看到EOF这个概念,这里需要明确的是并不存在EOF这样一个字符,它只是一个控制条件。起初,我认为EOF就是字面意思即,到达了文件的结尾(End of File)。

概述


我们在使用C标准I/O时,经常会看到EOF这个概念,这里需要明确的是并不存在EOF这样一个字符,它只是一个控制条件。起初,我认为EOF就是字面意思即,到达了文件的结尾(End of File)。可是,最近在看K&R时,发现函数返回时EOF表示的是当前函数调用出现了错误,这些错误包括:


  • 文件达到了末尾;


  • 文件读写出现了错误,比如,磁盘没有空间。


下面是man中,关于fgetc的解释:


fgetc() reads the next character from stream and returns it as an unsigned char cast to an int, 
or EOF on end of file or error.


下面是EOF的定义:


#define  EOF (-1)


下面通过一个示例讲解一下EOF的用法。


读取一个字符


fgetc这个函数每次从文件流中读取一个,其函数原型如下:


int fgetc(FILE *stream);


这个函数需要的注意地方有几点:


  1. 每次调用其都返回stream流的下一个字符。


  1. 函数返回类型为unsigned char(强制类型转换为int)正常情况下,是一个大于0的整数


  1. 如果到达文件末尾或发生错误,则返回EOF,通过feof和ferror区分是到达了文件末尾还是发生了错误


下面举一个关于fgetc的例子,其每从标准输入读取一个字符,并输出到标准输出,直到1)到达文件末尾;2)遇到错误。


#include <stdio.h>
int main(void)
{
    int c;
    while ((c = fgetc(stdin)) != EOF) {
        fputc(c, stdout);
    }
    if (feof(stdin)) {
        fprintf(stdout, "end of file.\n");
    }
    if (ferror(stdin)) {
        fprintf(stderr, "some error ocurred.\n");
    }
    return 0;
}


lhl@ubuntu20:~/work/BLOGS/C/io$ ./eof
hello
hello
^D         //使用Ctrl+D模拟达到文件末尾
end of file.


Unix I/O EOF?


Unix I/O中的read函数如何表示一个文件到达了文件的末尾了呢?下面是man中关于read返回值的解释:


#include <unistd.h>
 ssize_t read(int fd, void *buf, size_t count);
On  success, the number of bytes read is returned (zero indicates end of file), and the file position is 
advanced by this number.  It is not an error if this number is smaller than the number of bytes requested;
this may happen for example because fewer bytes are ac‐tually available right now (maybe because we were 
close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was 
interrupted by a signal.  See also NOTES.
On error, -1 is returned, and errno is set appropriately.  In this case, it is left unspecified whether
the file position (if any) changes.


这里有几点需要注意:


  1. read正常情况下,返回读取的字节数量;


  1. **0表示文件到达了末尾,Enf of File,Unix I/O EOF仅仅表示文件到达了末尾


  1. 返回值大于0,但小于count是正常的,表示文件剩余的字数量就是这么多;


  1. -1,表示read执行遇到到了错误,比如,被信号中断等。


网络编程中的EOF


网络编程中也会经常遇到EOF这样一个概念,确切的说EOF是由内核检测到的一种条件。上一节说了,当read返回0时,表明文件到达了末尾,网络编程也是类似的,当应用程序接收到一个由read返回的0值之后,它就会认为遇到了EOF这个条件,从而做出相应的处理。对于TCP连接来说,当一个进程主动关闭连接的一端时,本地read就会发出EOF信号,连接的另一端的进程在试图读取流中最后一个字节之后的字节时,会检测到EOF。


相关文章
|
人工智能 自然语言处理 Java
Spring AI,搭建个人AI助手
本期主要是实操性内容,聊聊AI大模型,并使用Spring AI搭建属于自己的AI助手、知识库。本期所需的演示源码笔者托管在Gitee上(https://gitee.com/catoncloud/spring-ai-demo),读者朋友可自行查阅。
4895 44
Spring AI,搭建个人AI助手
|
监控 安全 测试技术
现在公司都在用的CI/CD框架到底是什么?
现在公司都在用的CI/CD框架到底是什么?
7590 1
|
12月前
|
供应链 算法 API
借助唯品会 API,唯品会店铺运动商品库存管理优化
本文介绍如何利用唯品会API优化运动商品库存管理。运动商品因季节性和促销影响,库存波动大,传统管理易导致缺货或积压。通过唯品会API,可实现库存实时监控、销售数据同步与自动化补货。结合预测模型与API数据,店铺可降低成本、提升效率,并增强市场响应能力,实现智能化运营。
|
存储 机器学习/深度学习 编解码
基于STM32的车牌识别系统
基于STM32的车牌识别系统
1143 0
|
SQL XML Java
简单理解springboot的依赖注入
依赖注入,Dependency Injection,简称DI,是spring中的核心技术,此技术贯穿Spring全局,是必须要熟练掌握的知识点。在本文中,我们将要深入研究spring中的IOC和DI,理解核心思想,并学会如何在spring boot中使用基于java和注解的方式正确使用DI来创建spring应用程序。控制反转 IOC要理解DI,首先需要理解spring的核心思想之一,控制反转(In
3154 0
简单理解springboot的依赖注入
|
安全 Ubuntu Linux
在Linux中,如何卸载软件?
在Linux中,如何卸载软件?
|
存储 安全 算法
加盐哈希的科学原理及其重要性
【8月更文挑战第31天】
1398 0
|
API
QT学习—属于自己的串口调试助手
本文详细介绍了如何编写一个属于自己的串口助手。
2563 3
|
安全 Go 开发工具
go clean命令 完全解析
go clean命令 完全解析
2142 0
|
Shell 开发工具 git
Git下载安装及IDEA整合Git
Git下载安装及IDEA整合Git
Git下载安装及IDEA整合Git