You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何格式符%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;
}

疑问:

  1. 格式符%79[^\n]\n是引发段错误的原因吗?
  2. 编译该程序的硬件是否会影响运行结果?(使用的是搭载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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 08:01:23