自制cat函数时首字符丢失及末尾字符异常问题求助
实现Linux cat命令的两个问题修复方案
问题1:第二行开始首字符丢失的原因及修复
原代码中,每次用fgets读取一行后,额外调用了fgetc(file)读取下一个字符。fgets会把当前行(包括末尾的换行符)完整读入缓冲区,之后fgetc会读取下一行的第一个字符,这个字符被读取后没有输出,直接被丢弃,导致后续行首字符缺失。
修复方式:完全移除多余的fgetc判断逻辑,fgets已经能正确读取每行内容(含换行符),直接输出缓冲区内容即可。
问题2:最后一行末尾字符丢失的原因及修复
修改后的代码中,强行将line[strlen(line)-1]设为'\0',这会破坏原有内容:
- 如果行末尾有换行符,会把换行符删掉,之后手动加
\n输出看似正常,但属于多余操作 - 如果文件最后一行没有换行符,
strlen(line)得到的是该行有效字符长度,line[strlen(line)-1]就是最后一个有效字符,被替换为'\0'后直接丢失,导致输出少了末尾字符
修复方式:直接输出fgets读取的内容,不要修改缓冲区的末尾字符,保留文件原有换行格式。
正确的实现代码
#include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc, char *argv[]) { FILE *file = NULL; char line[4096]; int cur_file = 1; // 处理标准输入(无参数或参数为"-") if (argc == 1 || (strcmp(argv[1], "-") == 0)) { while (fgets(line, sizeof(line), stdin)) { printf("%s", line); } return 0; } // 遍历处理所有文件参数 while (cur_file < argc) { file = fopen(argv[cur_file], "r"); if (file == NULL) { fprintf(stderr, "%s: no such file or directory\n", argv[cur_file]); cur_file++; continue; } // 逐行读取并输出 while (fgets(line, sizeof(line), file)) { printf("%s", line); } fclose(file); cur_file++; } return 0; }
代码改进说明
- 移除了冗余的字符读取逻辑,保证每行内容完整输出
- 修复标准输入处理:原
scanf写法存在格式错误和缓冲区残留问题,改用fgets读取标准输入更可靠 - 优化错误处理:遇到不存在的文件时,输出错误信息后继续处理后续文件,符合cat命令的原生行为
- 简化变量结构,去掉无用的临时数组,提升代码简洁性
测试验证
使用你的测试文件b.txt执行./mycat b.txt b.txt,输出将与原文件内容完全一致:
Hello world! Great, one more file. Just what we need. Hello world! Great, one more file. Just what we need.
内容的提问来源于stack exchange,提问作者Zhunan Shuai
相关产品推荐
相关产品推荐

