模拟grep -f命令的C程序出现Segmentation fault (core dumped)问题求助
问题排查与代码优化(模拟
grep -f功能) 一、段错误原因分析
- 文件打开逻辑错误:原代码中
fopen("aux1","r")使用字符串字面量而非存储文件名的变量,导致尝试打开名为aux1的不存在文件,返回的file1/file2为空指针,后续fscanf操作空指针触发段错误。 - 未做参数合法性检查:直接访问
argv[1]和argv[2],若运行时传入参数不足2个(argc < 3),会访问非法内存地址触发段错误。 - 缓冲区溢出风险:
s1/s2仅分配100字节,若文件内容超过该长度,strcat会越界写入,破坏内存结构引发段错误。 - 空指针解引用:
strstr未找到匹配时返回NULL,直接用printf("%s", NULL)会触发段错误。 - 核心逻辑偏差:原代码将两个文件内容拼接成单一字符串后查找匹配,完全不符合
grep -f的实际逻辑——grep -f是用第一个文件的每一行作为匹配模式,在第二个文件的每一行中查找匹配,输出所有包含任意模式的行。
二、优化方案与修正代码
优化点说明
- 移除冗余的
aux1/aux2变量,直接用argv[1]、argv[2]作为文件名打开文件。 - 增加参数检查:参数不足时向
stderr输出错误提示并退出。 - 增加文件打开校验:文件打开失败时向
stderr输出错误信息并清理资源。 - 采用逐行处理逻辑,贴合
grep -f的实际功能。 - 使用足够大的缓冲区避免溢出,同时处理换行符。
修正后的代码
#include <stdio.h> #include <string.h> #include <stdlib.h> #define BUF_SIZE 1024 int main(int argc, char *argv[]) { // 检查参数数量是否足够 if (argc < 3) { fprintf(stderr, "用法: %s <模式文件> <目标文件>\n", argv[0]); exit(EXIT_FAILURE); } // 打开模式文件 FILE *pattern_file = fopen(argv[1], "r"); if (!pattern_file) { fprintf(stderr, "无法打开模式文件: %s\n", argv[1]); exit(EXIT_FAILURE); } // 打开目标文件 FILE *target_file = fopen(argv[2], "r"); if (!target_file) { fprintf(stderr, "无法打开目标文件: %s\n", argv[2]); fclose(pattern_file); exit(EXIT_FAILURE); } char pattern[BUF_SIZE]; char line[BUF_SIZE]; // 遍历每个模式行 while (fgets(pattern, BUF_SIZE, pattern_file) != NULL) { // 移除模式行末尾的换行符 size_t len = strlen(pattern); if (len > 0 && pattern[len-1] == '\n') { pattern[len-1] = '\0'; } // 跳过空模式行 if (strlen(pattern) == 0) { continue; } // 将目标文件指针重置到开头,匹配当前模式 rewind(target_file); // 遍历目标文件的每一行 while (fgets(line, BUF_SIZE, target_file) != NULL) { // 检查当前行是否包含模式 if (strstr(line, pattern) != NULL) { // 输出匹配的行(保留原换行符) fputs(line, stdout); } } } // 关闭文件资源 fclose(pattern_file); fclose(target_file); return 0; }
三、代码说明
- 错误输出规范:使用
fprintf(stderr, ...)向标准错误流输出提示,符合Unix工具的错误输出习惯,exit(EXIT_FAILURE)返回非0状态码标识运行失败。 - 资源安全:文件打开失败时会关闭已打开的其他文件,避免资源泄漏。
- 逻辑贴合:完全复刻
grep -f的逐模式、逐行匹配逻辑,输出符合预期的结果。 - 缓冲区安全:定义
BUF_SIZE为1024,足够处理大多数文本行,fgets会自动截断过长内容,避免缓冲区溢出。
内容的提问来源于stack exchange,提问作者Catalin Ionita
相关产品推荐
相关产品推荐

