PuTTY环境下C程序编译正常但报Segmentation fault求助
问题排查及修复方案
核心错误(直接导致段错误)
- 逻辑判断运算符写错:
if(infile = NULL)是赋值操作,会直接把infile设为NULL,正确写法是if(infile == NULL),赋值后后续读NULL指针指向的文件会直接触发段错误 - 参数校验顺序错误:你在没有判断
argc参数数量是否足够的情况下,直接访问argv[2]调用fopen,如果用户传入参数少于3个,argv[2]是非法内存地址,直接访问就会触发段错误,必须把参数校验逻辑放到程序最开头 - 缺少依赖头文件:调用
exit()函数需要包含<stdlib.h>头文件,否则程序行为未定义
其他潜在错误
- 宏定义错误:
NEWLINE的定义错误,正确写法是#define NEWLINE '\n',你当前直接把换行符写在单引号里属于语法错误 - 变量类型错误:
getc()返回值是int类型,你用char类型存返回值,如果系统中char是无符号类型,永远无法匹配EOF(值为-1),会导致死循环,正确写法是把char c;改成int c; - 资源泄漏:打开的文件指针使用结束后没有调用
fclose()关闭,虽然进程退出后系统会自动回收,但属于不规范写法 - 容错逻辑缺失:如果用户传入的第一个参数不是
-s或-f,程序没有错误提示,直接无响应退出
修复后参考代码
#include <stdio.h> #include <string.h> #include <stdlib.h> // 新增exit所需头文件 #define BLANK ' ' #define NEWLINE '\n' // 修正换行符宏定义 int main (int argc, char *argv[]) { FILE *infile; int c; // 修正为int类型适配getc返回值 int char_count = 0; // 最先校验参数合法性 if (argc != 3 && argc !=4) { fprintf(stderr, "用法:%s -s 输入文件名 或 %s -f 输入文件名 输出文件名\n", argv[0], argv[0]); exit(1); } infile = fopen(argv[2], "r"); // 修正判断相等的运算符 if(infile == NULL) { fprintf(stderr, "%s: 无法打开 %s \n", argv[0], argv[2]); exit(1); } while ( (c = getc(infile)) != EOF) if ((c != BLANK) && (c != NEWLINE) ) char_count++; if (argc == 3) { if(strcmp(argv[1], "-s") == 0) { printf ("%d characters\n", char_count); } else { fprintf(stderr, "不支持的参数:%s\n", argv[1]); fclose(infile); exit(1); } } else if (argc == 4) { if(strcmp(argv[1], "-f") == 0) { FILE *outfile; outfile = fopen(argv[3], "w"); if(outfile == NULL) { fprintf(stderr, "错误:无法打开输出文件\n"); fclose(infile); exit(1); } fprintf (outfile, "My file has %d chars\n", char_count); fclose(outfile); // 关闭输出文件 } else { fprintf(stderr, "不支持的参数:%s\n", argv[1]); fclose(infile); exit(1); } } fclose(infile); // 关闭输入文件 return 0; }
内容的提问来源于stack exchange,提问作者Tai Quach
相关产品推荐
相关产品推荐

