C程序创建文件后挂起求助:分割文件功能异常排查
问题分析与修复方案
核心问题:运算符优先级错误
你的程序创建空part1.txt并挂起的根本原因是赋值操作与比较操作的优先级混淆。在C语言中,<运算符的优先级高于=,所以类似fd=open(...) < 0的语句会先执行open(...) < 0,将比较结果(0或1)赋值给文件描述符变量,而不是先把open的返回值赋值给变量再做比较。
这会导致fd、fd1、fd2被错误地赋值为0或1(而非正确的文件描述符,通常从3开始),后续对这些错误文件描述符的read/write操作完全无法正常工作,最终导致程序挂起、输出文件为空。
需要修正的关键点
1. 修复所有open语句的优先级问题
给赋值表达式加上括号,确保先完成文件描述符的赋值,再进行错误判断:
原代码:
if (fd=open(argv[1], O_RDONLY) < 0)
修正后:
if ((fd=open(argv[1], O_RDONLY)) < 0)
同样的修改要应用到fd1和fd2的open判断语句中。
2. 修正参数数量检查
你的程序需要接收两个参数(输入文件名+分割字节数),但原代码判断argc<2,这会导致用户只输入一个参数时,程序仍会执行atoi(argv[2]),触发数组越界访问。修正为:
if(argc<3){ printf("请输入两个参数:文件名 分割字节数\n"); exit(1); }
3. 其他细节优化
- 补全缺失的头文件:原代码未包含
fcntl.h、unistd.h等系统调用所需的头文件,会导致编译警告或错误 perror的错误信息尽量清晰,避免多余换行- 初始化文件描述符变量为
-1,避免未初始化的潜在问题 - 创建输出文件时添加
O_TRUNC标志,确保清空已存在的文件内容 - 优化读写逻辑,避免不必要的单字节循环读取,提升效率
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> int splitter; int fd = -1, fd1 = -1, fd2 = -1; char buffer[5000]; int main(int argc, char** argv){ if(argc<3){ printf("请输入两个参数:文件名 分割字节数\n"); exit(1); } splitter = atoi(argv[2]); if ((fd=open(argv[1], O_RDONLY)) < 0){ perror("打开输入文件失败"); exit(1); } if ((fd1=open("part1.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) <0){ perror("创建part1.txt失败"); exit(1); } ssize_t read_bytes = read(fd, buffer, splitter); if(read_bytes == splitter){ write(fd1, buffer, splitter); if ((fd2=open("part2.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU))<0){ perror("创建part2.txt失败"); exit(1); } ssize_t remaining; while ((remaining = read(fd, buffer, sizeof(buffer))) > 0){ write(fd2, buffer, remaining); } close(fd2); } else if(read_bytes > 0){ write(fd1, buffer, read_bytes); ssize_t remaining; while((remaining = read(fd, buffer, sizeof(buffer))) >0){ write(fd1, buffer, remaining); } } close(fd1); close(fd); return 0; }
编译与执行
编译命令:
gcc -o split split.c
执行命令:
./split text.txt 10
内容的提问来源于stack exchange,提问作者Ric97
相关产品推荐
相关产品推荐

