为何格式符%79[^ ] 会导致C程序出现段错误?
关于C程序段错误的疑问
以下C代码运行时出现segmentation fault(段错误):
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char line[80]; FILE *in = fopen("spooky.csv", "r"); FILE *file1 = fopen("ufos.csv", "w"); FILE *file2 = fopen("disappearances.csv", "w"); FILE *file3 = fopen("others.csv", "w"); while (fscanf(in, "%79[^\n]\n", line) == 1) { if (strstr(line, "UFO")) fprintf(file1, "%s\n", line); else if (strstr(line, "Disappearance")) fprintf(file2, "%s\n", line); else fprintf(file3, "%s\n", line); } fclose(file1); fclose(file2); fclose(file3); return 0; }
疑问:
- 格式符
%79[^\n]\n是引发段错误的原因吗? - 编译该程序的硬件是否会影响运行结果?(使用的是搭载7代Intel Core i7的Fedora 38工作站系统)
问题解答
1. 格式符%79[^\n]\n不是段错误的直接原因,但存在使用隐患
这个格式符本身不会触发段错误:
%79[^\n]最多读取79个字符,刚好适配line数组的80字节长度(留1字节存字符串终止符),不会造成数组越界;- 末尾的
\n是让fscanf跳过换行符,但如果文件最后一行没有换行符,或是遇到空行,fscanf会陷入等待,但这不会直接引发段错误。
真正导致段错误的核心问题是未检查文件指针的有效性:
- 如果
spooky.csv不存在、路径错误或无读取权限,in会返回NULL,此时调用fscanf(in, ...)属于空指针解引用,直接触发段错误; - 同理,若
ufos.csv等输出文件无法创建(比如目录无写入权限),对应的file1/file2/file3会是NULL,后续调用fprintf也会触发段错误。
2. 硬件不会直接影响运行结果
你使用的7代Intel Core i7 + Fedora 38系统,硬件本身和这个段错误无关。段错误是程序逻辑漏洞(空指针访问)导致的,只要是符合C标准的系统,空指针解引用都会触发段错误——不同系统可能错误提示的形式略有差异,但本质原因完全一致。
修复建议:
- 每次调用
fopen后必须检查返回值,例如:FILE *in = fopen("spooky.csv", "r"); if (in == NULL) { perror("Failed to open spooky.csv"); exit(EXIT_FAILURE); } - 替换
fscanf为更安全的fgets读取整行,避免格式符的潜在问题:while (fgets(line, sizeof(line), in) != NULL) { // 去掉换行符(如果存在) line[strcspn(line, "\n")] = '\0'; // 原有的判断逻辑保持不变 } - 原代码漏掉了关闭输入文件指针
in,记得补充fclose(in);。
内容的提问来源于stack exchange,提问作者arantebw
相关产品推荐
相关产品推荐

