实现类cat命令lolcat时触发Segmentation Fault问题求助
解决lolcat命令带
-n参数时的段错误问题 核心错误分析与修复
1. 字符串比较方式错误
C语言中不能直接用==比较字符串内容,argv[1] == "-n"比较的是指针地址而非字符串内容,导致带-n参数时,command值错误设为1,循环会尝试打开"-n"这个不存在的文件,操作空指针引发段错误。
修复:使用strcmp函数比较字符串,需包含<string.h>头文件:
#include <string.h> // ... if(argc > 1 && strcmp(argv[1], "-n") == 0) { command = 2; } else{ command = 1; }
2. 未检查命令行参数数量
当用户未传入任何参数时,argv[1]不存在,直接访问会导致数组越界。需先判断argc最小值:
if(argc < 2) { fprintf(stderr, "用法: %s [-n] 文件名...\n", argv[0]); return 1; }
3. 未检查文件是否成功打开
调用fopen后必须检查返回值是否为NULL,避免操作空指针:
myFile = fopen(argv[i], "r"); if(myFile == NULL) { fprintf(stderr, "无法打开文件: %s\n", argv[i]); continue; // 跳过当前文件,处理下一个 }
4. 数组越界风险
word[255]大小固定,若文件某行长度超过254字符,x++会导致数组越界。可在循环中检查x范围,处理超长行:
while((c = fgetc(myFile)) != EOF) { if(x >= 254) { if(command == 1) { for(int j = x - 1 ; j>=prev_c_count ; j--) { printf("%c" , word[j]); } } prev_c_count += x - prev_c_count; x = 0; } word[x] = c; c_count++; // ... 其余代码 }
5. 补全-n统计行数功能
当前代码仅统计l_count但未输出,需在command == 2时补充总行数输出:
if(command == 2) { printf("\n文件 %s 的总行数: %d\n", argv[i], l_count); }
修复后的完整代码示例
#include <stdio.h> #include <string.h> int main(int argc , char *argv[]) { if(argc < 2) { fprintf(stderr, "用法: %s [-n] 文件名...\n", argv[0]); return 1; } int command = 0; if(strcmp(argv[1], "-n") == 0) { command = 2; if(argc < 3) { fprintf(stderr, "用法: %s -n 文件名...\n", argv[0]); return 1; } } else{ command = 1; } for(int i = command ; i < argc ; i++) { FILE *myFile = NULL; myFile = fopen(argv[i] , "r"); if(myFile == NULL) { fprintf(stderr, "无法打开文件: %s\n", argv[i]); continue; } char word[255]; char c; int c_count = 0; int l_count = 0; int prev_c_count = 0; int x = 0; while((c = fgetc(myFile)) != EOF) { if(x >= 254) { if(command == 1) { for(int j = x - 1 ; j>=prev_c_count ; j--) { printf("%c" , word[j]); } } prev_c_count += x - prev_c_count; x = 0; } word[x] = c; c_count++; if(c == '\n') { l_count++; if(command == 1) { for(int j = c_count - 1 ; j>=prev_c_count ; j--) { printf("%c" , word[j]); } } prev_c_count = c_count; x = 0; } else { x++; } } if(c_count > prev_c_count) { l_count++; if(command == 1) { for(int j = c_count - 1 ; j>=prev_c_count ; j--) { printf("%c" , word[j]); } } } if(command == 2) { printf("\n文件 %s 的总行数: %d\n", argv[i], l_count); } else { printf("\n"); } fclose(myFile); } return 0; }
内容的提问来源于stack exchange,提问作者Adam Saleem
相关产品推荐
相关产品推荐

