文本文件每行按空格截断内容的C语言实现异常求助
问题分析与修复方案
嘿,你的代码核心思路是对的,但出现行内容混淆的主要原因是错误地把feof()当循环判断条件,还有几个细节处理不到位,我来帮你逐一解决:
为啥会出现行内容混淆?
最关键的问题就是while(!feof(input))这个循环条件:feof()只有在你尝试读取文件末尾之后才会返回真。举个例子,当你读完最后一行有效内容时,feof()还是false,循环会再跑一次——这时候fgets()会返回NULL,但你依然会处理之前留在line数组里的旧内容,这不就导致行内容重复/混淆了嘛!
另外还有两个小问题:
- 没处理参数错误、文件打开失败的情况,出问题了连个提示都没有,调试起来头大;
- 用
strtok()有点大材小用,而且它会修改全局状态,线程不安全,其实我们只需要找第一个空格就行。
修复后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { FILE *input = NULL, *output = NULL; char line[40]; // 先检查参数对不对 if (argc != 3) { fprintf(stderr, "用法: %s <输入文件> <输出文件>\n", argv[0]); return EXIT_FAILURE; } // 打开输入文件,失败就报错 input = fopen(argv[1], "r"); if (input == NULL) { perror("打开输入文件失败"); return EXIT_FAILURE; } // 打开输出文件,失败要先关输入文件再退出 output = fopen(argv[2], "w"); if (output == NULL) { perror("打开输出文件失败"); fclose(input); return EXIT_FAILURE; } // 正确的循环方式:用fgets的返回值判断,读到有效内容才处理 while (fgets(line, sizeof(line), input) != NULL) { // 找第一个空格的位置 char *space_ptr = strchr(line, ' '); if (space_ptr != NULL) { // 把空格改成字符串结束符,直接截断后面的内容 *space_ptr = '\0'; } // 写入输出文件,原行的换行符会被保留(如果有的话) fputs(line, output); } // 用完文件记得关 fclose(input); fclose(output); return EXIT_SUCCESS; }
关键改进点说明
- 换循环条件:用
fgets() != NULL判断,只要成功读取一行就处理,读到文件尾或出错就直接退出,彻底解决旧内容重复处理的问题; - 用
strchr替代strtok:strchr()专门找字符第一次出现的位置,比strtok更简单安全,找到空格后替换成'\0'就完成截断; - 补全错误处理:参数不对给用法提示,文件打开失败用
perror()输出具体错误(比如权限不够、文件不存在),还避免了资源泄漏; - 初始化指针:把
input和output初始化为NULL,防止野指针搞事情。
这样改完后,代码就能准确实现每行只保留第一个空格前的内容,不会再出现行内容混淆的情况啦!
内容的提问来源于stack exchange,提问作者StYl3z
相关产品推荐
相关产品推荐

