【问题标题】:Segmentation fault from command line arguments in cc中命令行参数的分段错误
【发布时间】:2015-12-04 22:58:39
【问题描述】:

我正在尝试读取一个文件并从该文件创建一个邻接列表,但是当我从命令行读取该文件时,我得到一个分段错误 gcc n00889642.c ./a.out test.txt 分段错误

为什么会这样?

main(int argc, char *argv[]){

    int index;
    int i;
    char vertex1;
    char vertex2;
    FILE *f = fopen(argv[1], "r");
    while (fscanf(f, " %c %c", vertex1, vertex2) != EOF)
    {
        for(i = 0; i<26; i = i + 1)
        {
            if(i == vertexCount)
            {
                InsertVertex(vertex1);
                break;
            }
            if(strcmp(graph[i], vertex1) == 0)
            {
                break;
            }
        }
        for(i=0; i<26; i = i + 1)
        {
            if(i == vertexCount)
                InsertVertex(vertex2);
            if(strcmp(graph[i], vertex2)== 0)
                break;
        }
    }
    fclose(f);
    i = 1;
    while(i < vertexCount)
    {
        insertEdge(graph[0].vertexKey, graph[i].vertexKey);
        i= i + 1;
    }
    f = fopen(argv[1], "r");
    while(fscanf(f, " %c %c", vertex1, vertex2) != EOF)
    {
        if(strcmp(graph[0], vertex1) != 0)
            insertEdge(vertex1, vertex2);
    }
    fclose(f);

    printGraph();
    return 0;
}

这是我的代码的主要部分

【问题讨论】:

  • 调试一下就知道了。显然你没有尝试过 - 你甚至没有检查fopen的结果@
  • 遇到段错误时,通常应该尝试的第一件事是启用调试符号并在调试器中运行。这会告诉你程序的哪一行崩溃了。但是,在该行之前通常会出现逻辑错误,导致指针包含垃圾。你想预防这些,而不是治愈它们。养成的好习惯:在写入数组之前检查数组的边界。检查库调用中的错误。使用assert()static_assert() 确保您对程序状态的假设是正确的。每当你使用指针时,你应该知道为什么它是正确的。
  • 您还应该打开编译器警告并注意它们。在 GCC/Clang 上,这是 -g -Wall -Wextra -pedantic。 Clang 还允许-Weverything

标签: c segmentation-fault


【解决方案1】:

几件事:

argv[1] - 如果只传入一个参数,应该是 argv[0](应该验证 argc)。

fscanf(f, " %c %c", vertex1, vertex2)

scanf 需要变量的地址来保存值,所以应该是:

fscanf(f, " %c %c", &vertex1, &vertex2)

【讨论】:

    【解决方案2】:

    您的fscanf 语句中有错误

    while (fscanf(f, " %c %c", vertex1, vertex2) != EOF)
    

    您应该提供目标变量的地址。最好检查转换的字段数

    while (fscanf(f, " %c %c", &vertex1, &vertex2) == 2)
    

    还有

     if(strcmp(graph[i], vertex1) == 0)
    

    不理会编译器警告,很可能会导致段错误。从您不完整的代码中不清楚vertex1vertex2 真正应该是什么数据类型

    InsertVertex(vertex2);
    

    char 怎么可能是顶点?

    【讨论】:

    • 我更改了两个 fscanf 但我仍然收到分段错误,我不太精通 C,如果我不得不使用它,我似乎经常遇到这个错误。程序读取到有两个参数(程序本身和我要读取的文件),但读取它似乎有问题
    • 程序完全编译,所有用于比较的数据类型都是正确的,我认为问题可能出在我的 fopen 上,但我真的不知道如何检查。
    • @frznbullet 答案已更新。我不相信你没有编译器警告。他们启用了吗? “所有用于比较的数据类型都是正确的”——它们不是。 strcmp 不接受任何 char 参数。
    • 您可以通过阅读手册页来检查 fopen 错误。是你做的吗? if (f == NULL)
    • 我的 fopen 确实打开了文件,我试图让我的程序只打印文件中的所有对象并在 while (fscanf(f, "%c %c", &vertex1, &vertex2) == 2)
    猜你喜欢
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 2020-11-19
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    • 2019-03-19
    相关资源
    最近更新 更多