代码中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; }
修复要点说明
- 把
buf_in()的返回类型改成int,main里用int ch接收返回值,确保能正确判断EOF。 - 在
buf_in()里处理read的返回值,遇到文件结束或读取错误时直接返回EOF,避免重复输出旧数据。 - 新增
flush_output()函数,循环结束后调用,确保输出缓冲区里的剩余数据全部写入文件。 - 打开输出文件时添加
O_TRUNC标志,避免文件原有内容残留;同时增加文件打开失败的错误处理,防止后续操作出错。 - 显式声明所有全局变量,消除编译警告。
内容的提问来源于stack exchange,提问作者ECH
相关产品推荐
相关产品推荐

