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

代码中while循环无法通过EOF终止,输出文件内容异常求助

代码问题分析及修复方案

你的代码存在以下几个关键问题,导致了输出异常和循环无法终止:

  • char类型无法正确匹配EOF:EOF是int类型(通常值为-1),如果你的系统中char是无符号类型,把buf_in()的返回值赋值给char ch后,-1会被转成255,永远不可能等于EOF,循环也就停不下来。
  • 未处理read的返回结果:
    • 当read返回0时,说明文件已经读完,但你的代码还会继续返回缓冲区里的旧数据,导致输入内容重复输出。
    • 如果read返回-1(读取出错),代码也没做处理,会一直无效读取。
  • 输出缓冲区未收尾:循环结束时,buffer_out里可能还有没写入文件的剩余数据,你没调用write把这部分数据输出。
  • 全局变量未声明:代码里用的fd_in、fd_out、read_pos、write_pos、buffer_in、buffer_out都是全局变量,但没显式声明,会引发编译警告甚至未定义行为。

修复后的完整代码

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

// 显式声明全局变量
int fd_in, fd_out;
int read_pos = 0, write_pos = 0;
char buffer_in[16];
char buffer_out[16];

// 返回值改为int,兼容EOF的存储
int buf_in()
{
    if (read_pos == 16)
    {
        read_pos = 0;
        ssize_t ret = read(fd_in, buffer_in, 16);
        if (ret == 0)  // 文件读取完毕
            return EOF;
        if (ret == -1)  // 读取错误,打印错误信息
        {
            perror("read failed");
            return EOF;
        }
    }
    // 转成无符号char再返回,避免符号扩展问题
    return (unsigned char)buffer_in[read_pos++];
}

void buf_out(char data)
{
    if (write_pos == 16)
    {
        write(fd_out, buffer_out, 16);
        write_pos = 0;
    }
    buffer_out[write_pos++] = data;
}

// 新增函数:刷新输出缓冲区剩余数据
void flush_output()
{
    if (write_pos > 0)
    {
        write(fd_out, buffer_out, write_pos);
        write_pos = 0;
    }
}

int main()
{
    fd_in = open("input.txt", O_RDONLY);
    if (fd_in == -1)
    {
        perror("failed to open input.txt");
        return 1;
    }
    // 加上O_TRUNC,清空文件原有内容;补充权限参数的正确写法
    fd_out = open("result.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (fd_out == -1)
    {
        perror("failed to open result.txt");
        close(fd_in);
        return 1;
    }
    
    int ch;  // 用int存储buf_in的返回值,正确识别EOF
    while ((ch = buf_in()) != EOF)
    {
        buf_out((char)ch);
    }
    
    flush_output();  // 循环结束后,把剩余的输出数据写入文件
    close(fd_in);
    close(fd_out);
    return 0;
}

修复要点说明

  1. 把buf_in()的返回类型改成int,main里用int ch接收返回值,确保能正确判断EOF。
  2. 在buf_in()里处理read的返回值,遇到文件结束或读取错误时直接返回EOF,避免重复输出旧数据。
  3. 新增flush_output()函数,循环结束后调用,确保输出缓冲区里的剩余数据全部写入文件。
  4. 打开输出文件时添加O_TRUNC标志,避免文件原有内容残留;同时增加文件打开失败的错误处理,防止后续操作出错。
  5. 显式声明所有全局变量,消除编译警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 19:55:13