为什么“%79[^ ] “导致分段错误?

问题描述 投票:0回答:1
#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;
}

此代码返回分段错误的运行时错误。

我在什么硬件上编译这个程序有关系吗?我使用的是带有 Intel Core i7(第 7 代)的 Fedora 38(工作站)。

c gdb
1个回答
0
投票

该问题与

fscanf
格式无关:如错误消息中所示,内部函数
s
的参数
__vfscanf_internal
具有值
0x0
,指示为
FILE *
参数传递了一个空指针.

您应该检查

fopen
是否无法打开文件,并使用有意义的错误消息报告此情况。

另请注意以下备注:

  • 你应该关闭
    in
  • 您可以使用
    fgets()
    代替
    fscanf()
    格式。
  • fscanf
    格式将无法转换 spooky.csv 中的初始空行,如果它是实际的 CSV 文件,则不应发生这种情况。
  • 转换规范中的尾部
  • \n
     将导致换行符与下一行中的任何初始空白一起被消耗,这可能不是有意的。使用 
    %79[^\n]%*[\n]
     可以避免这种情况,但会消耗后续的空行。
  • cde 会默默地将长行分成 79 字节的块。修改任意长行的代码并不简单,但更大的缓冲区可能是一个不错的选择。
这是修改后的版本:

#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> FILE *fopen_check(const char *filename, const char *mode) { FILE *fp = fopen(filename, mode); if (fp == NULL) { fprintf(stderr, "cannot open %s: %s\n", filename, strerror(errno)); exit(1); } return fp; } int main(void) { char line[80]; FILE *in = fopen_check("spooky.csv", "r"); FILE *file1 = fopen_check("ufos.csv", "w"); FILE *file2 = fopen_check("disappearances.csv", "w"); FILE *file3 = fopen_check("others.csv", "w"); fscanf(in, "%*[\n]"); // skip initial empty lines 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(in); fclose(file1); fclose(file2); fclose(file3); return 0; }
    
© www.soinside.com 2019 - 2024. All rights reserved.