You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用read()逐字符读取文件?无法使用fgetc且EOF判断失效求助

解决read()逐字符读取文件并判断EOF的问题

嘿,我看了你的代码,发现几个关键问题导致你没法正确实现需求,咱们一步步来梳理和修正:

你的代码里的核心问题

  • 变量c的类型完全错了:你声明了int *c = '\0';,把c定义成了指针,但你需要的是一个用来存储读取字符的普通int变量(必须是int,不能用char——因为EOF是int类型的宏,值为-1,用char的话会有符号匹配问题,比如遇到ASCII 0xFF的字符时会被误判为EOF)。
  • 判断EOF的方式不对:你直接用c == EOF来判断,但实际上read()系统调用的返回值才是判断文件结束或错误的依据:
    • 返回0:代表已经读到文件末尾(EOF)
    • 返回-1:代表读取过程中发生错误
    • 返回1:代表成功读取了1个字节的内容
  • 打印逻辑错误:原来的printf("%c\n", c);因为c是指针,会打印指针地址对应的随机字符,完全不符合预期。

修正后的代码

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    // 简单处理命令行参数
    if (argc < 2) {
        fprintf(stderr, "请传入要读取的文件名:%s <filename>\n", argv[0]);
        return EXIT_FAILURE;
    }
    const char *inFileName = argv[1];
    
    int infile = open(inFileName, O_RDONLY); 
    if (infile < 0 ) {
        perror("打开文件失败");
        return EXIT_FAILURE; 
    } 
    
    int c; // 用int存储读取的字符,兼容EOF的判断
    ssize_t read_ret; // 存储read()的返回值
    int i = 0; 
    
    // 最多读取30个字符,或者遇到文件结束/错误就停止
    while (i < 30) {
        read_ret = read(infile, &c, 1); 
        
        if (read_ret == 0) {
            printf("已到达文件末尾\n");
            break;
        } else if (read_ret == -1) {
            perror("读取文件出错");
            close(infile); // 出错时记得关闭文件
            return EXIT_FAILURE;
        }
        
        // 成功读取一个字符,打印出来
        printf("%c\n", c); 
        i++;
    }
    
    close(infile); // 务必关闭文件句柄,避免资源泄漏
    return EXIT_SUCCESS;
}

额外注意点

  1. 为什么要用int存字符?因为EOF是int类型,值为-1,如果用signed char存储,当读取到ASCII值为0xFF的字符时,会被解释为-1,和EOF混淆,导致误判文件结束;用unsigned char的话,永远不会等于-1,也就没法判断EOF。
  2. 一定要检查read()的返回值,这是Unix系统调用的基本规范——系统调用可能因为各种原因(比如文件被意外关闭、权限问题)出错,必须处理这些情况。
  3. 最后别忘了调用close(infile)关闭文件句柄,否则会造成文件描述符泄漏,长时间运行可能耗尽系统资源。

内容的提问来源于stack exchange,提问作者code kid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:12:05