我不知道导致分段错误的原因

时间:2017-04-08 23:49:53

标签: c segmentation-fault switch-statement

我正在尝试创建一个简单的日记",您可以在其中添加工作人员,然后写下他们工作了多少小时。但是每次进入switch语句,都会出现分段错误。我不知道是什么导致它,我的知识还没有达到我自己能找到的水平。 代码:

include <stdio.h>
include <stdlib.h>
include <string.h>

int vybera(int pocet){
    int vyber;
    int i;
    printf("\nKtery zamestnanec?\n");
    for(i = 0; i < pocet; i++){
        printf("%d\n", i + 1);
    }
    scanf("%d", vyber);
    return vyber;
}

int main(int argc, char** argv) {
    int worker;
    int pocet;
    int i;
    int vyber;
    int pomoc;
    int odprac = 0;
    printf("Kolik zamestnancu chcete pridat: ");
    scanf("%d%*c", &pocet);
    char workforce[pocet][100];
    printf("Zadejte %d jmen: \n", pocet);
    for(i = 0; i < pocet; i++){
        gets(workforce[i]);
    }
    for(i = 0; i < pocet; i++){
        printf("%s\n", workforce[i]);
    }
    vyber = vybera(pocet);
    switch(vyber){
        case 1:
            worker = vyber - 1;
            printf("Vybrali jste %s.\n", workforce[worker]);
            printf("Pocet odprac. hodin: ");
            scanf("%d", pomoc);
            odprac += pomoc;
            strcat(workforce[worker], (", %c", odprac + '0'));
            break;
        case 2:
            worker = vyber - 1;
            printf("Vybrali jste %s.\n", workforce[worker]);
            printf("Pocet odprac. hodin: ");
            scanf("%d", pomoc);
            odprac += pomoc;
            strcat(workforce[worker], (", %c", odprac + '0'));
            break;
        case 3:
            worker = vyber - 1;
            printf("Vybrali jste %s.\n", workforce[worker]);
            printf("Pocet odprac. hodin: ");
            scanf("%d", pomoc);
            odprac += pomoc;
            strcat(workforce[worker], (", %c", odprac + '0'));
            break;
        case 4:
            worker = vyber - 1;
            printf("Vybrali jste %s.\n", workforce[worker]);
            printf("Pocet odprac. hodin: ");
            scanf("%d", pomoc);
            odprac += pomoc;
            strcat(workforce[worker], (", %c", odprac + '0'));
            break;
        case 5:
            worker = vyber - 1;
            printf("Vybrali jste %s.\n", workforce[worker]);
            printf("Pocet odprac. hodin: ");
            scanf("%d", pomoc);
            odprac += pomoc;
            strcat(workforce[worker], (", %c", odprac + '0'));
            break;
        default:
            printf("Spatny vyber.\n");
    }   
    for(i = 0; i < pocet; i++){
        printf("%s\n", workforce[i]);
    }
    return (EXIT_SUCCESS);
}

我真的在我的智慧结束,需要我能得到的每一个帮助。即使对于分段错误主题有很多问题,我之所以发布这个问题的原因是它们都没有使用我的代码。我感谢您的帮助和耐心。 编辑:我来自Czechia,因此为什么我的大多数变量和我的所有printf输出都是捷克语。仅供参考。

3 个答案:

答案 0 :(得分:2)

更改:scanf(“%d”,vyber); to scanf(“%d”,&amp; vyber)对pomoc做同样的事;
说明:因为vyber变量是int,所以需要使用“&amp;”显式传递地址值。 &符号,与字符串(隐式传递其地址)不同。分段错误表示您正在尝试访问不属于您的内存。在这种情况下,vyber。

答案 1 :(得分:2)

scanf("%d", pomoc);

这是scanf()函数的错误语法。它应该是:

scanf("%d", &pomoc);

vyber

的输入语句中复制了同样的错误
scanf("%d", &vyber)

这是因为您尝试使用scanf()函数访问内存中的越界位置。由于您没有引用变量vyberpomoc,编译器会尝试访问内存点,其地址等于vyberpomoc中存储的变量。比这些各自变量的内存位置。这会导致未定义的行为,这就是你遇到seg-fault的原因。

答案 2 :(得分:2)

您已经被告知问题出在哪里,但让我简单提一下您如何自己找到(下一个)问题。基本上,有(至少)三种方式:

  1. 使用调试器逐行运行程序,直到崩溃为止。调试器还允许您停止程序并检查任何变量的值以查看代码实际执行的操作。

    您还没有告诉我们您使用的操作系统,编译器和IDE(如果有的话),因此我无法推荐任何特定的调试器(在任何情况下都是如此)不是SO的主题,但几乎可以肯定的是,您的系统可以使用调试器,无论它是什么。学习如何使用调试器需要花费一些精力,但它肯定值得。

    1. 如果由于某种原因你不能或不想使用调试器,你可以做“穷人的调试”#34;在代码中添加printf()语句,以显示正在发生的事情。这样,您可以看到程序在崩溃前的程度,并且您还可以打印出变量的值,以便更好地了解发生的情况。

      我建议打印到标准错误流(使用fprintf(stderr, "...")),因为它不会干扰程序的正常输出,并且因为每次打印到错误流时都会自动刷新错误流它,如果程序崩溃,那么缓冲输出就没有丢失的风险。

      一个有用的技巧是使用if (DEBUG)为这样的调试打印语句添加前缀,如下所示:

      if (DEBUG) fprintf(stderr, "This is an example of debugging output.\n");
      

      然后,在程序的顶部,添加如下行:

      #define DEBUG 1
      

      这样,您可以通过将1更改为0来轻松关闭调试输出。 (还有更高级的方法可以在编译时更改定义,或者根据构建目标配置IDE来更改它,但这不在答案的范围之内。)

      1. 最后,您可以进行&#34;二分调试&#34;。基本上,制作程序的副本(或者,更好的是,将其提交到版本控制系统中)并开始删除部分代码,直到问题停止发生。此时,您将知道问题与您删除的最后一段代码中的内容有关。然后,您可以撤消最近的更改,并删除其他内容,并继续执行此操作,直到您将程序缩减为仍然显示问题的simplest possible example为止。

        此时,应该很容易看出问题所在,因为您不再需要任何不相关的代码来分散您的注意力。或者,如果没有,至少你有一小段代码可以清楚地演示问题,你可以在Stack Overflow上发帖以寻求帮助。 :)