调用scanf后代码崩溃

时间:2015-09-25 18:32:52

标签: c function

我是一名编程初学者,我的代码需要帮助。它应该是一个包含main的6个函数的计算器。四个用于操作,一个用于输入两个数字。一旦我输入数字的第二个输入,它就会崩溃。此外,我将函数input()中的值返回到main函数以执行操作时遇到问题。也许它与扫描opt有关?

#include <stdio.h>

int add(int n1, int n2);
int subtract(int n1, int n2);
int multiply(int n1, int n2);
int divide(int n1, int n2);
void input(int *n1, int *n2);


int main(void)
{
    int n1, n2, ret;
    char opt;


    input(&n1, &n2);

    printf("Addition -> 1\nSubtraction -> 2\nMultiplication -> 3\nDivision -> 4\nReset -> R\nExit -> E\n");

    scanf("%c", &opt);



    switch(opt){
            case '1': 
                ret = add(n1, n2);
                printf("The sum is %d\n", ret);
                break;
            case '2':
                ret = subtract(n1, n2);
                printf("The difference is %d\n", ret);
                break;
            case '3': 
                ret = multiply(n1, n2);
                printf("The sum is %d\n", ret); 
                break;              
            case '4': 
                ret = divide(n1, n2);
                printf("The sum is %d\n", ret);
                break;
    }

    return 0;   

}


void input(int *n1, int *n2)
{
    int a, b;   

    printf("Enter first number: \n");
    scanf("%d", &n1);

    printf("Enter second number: \n");
    scanf("%d", &n2);   

    *n1 = a;
    *n2 = b;
}

add(n1, n2)
{
    int result;
    result = (n1+n2);
    return result;
}

subtract(n1, n2)
{
    int result;
    result = (n1-n2);
    return result;
}

divide(n1, n2)
{
    int result;
    result = (n1/n2);
    return result;
}

multiply(n1, n2)
{
    int result;
    result = (n1*n2);
    return result;
}

我甚至做得对吗?

4 个答案:

答案 0 :(得分:2)

问题出在input

printf("Enter first number: \n");
scanf("%d", &n1);

printf("Enter second number: \n");
scanf("%d", &n2);   

%d格式说明符需要int *参数。由于n1n2已经int *,因此&n1&n2的类型为int **。这会导致分段错误。

要解决此问题,只需传入n1n2

void input(int *n1, int *n2)
{
    printf("Enter first number: \n");
    scanf("%d", n1);

    printf("Enter second number: \n");
    scanf("%d", n2);   

    getchar();
}

您注意到,如果您这样做,则不需要ab。另请注意调用getchar()以使用输入缓冲区中的换行符。如果您不这样做,换行符将由scanf中的main获取,并且不会输入切换语句。

此外,您的四个数学函数不指定返回类型。由于这些函数的原型将它们声明为返回int,并且因为int是函数的默认返回类型,所以它设法工作。但是,您应始终指定返回类型。

答案 1 :(得分:1)

scanf获取指向整数的指针,但是错误地将指针传递给指向整数的指针。

修正:

void input(int *n1, int *n2)
{
    int a, b;   

    printf("Enter first number: \n");
    scanf("%d", n1);

并且您不需要ab,输入中的值会直接写入指向的指针。在调用 main 函数中的'\n'之前,您还必须从输入流中读取scanf("%c", &opt);。否则,当您希望阅读选项字符时,您将阅读换行符。

在评论中解决您的问题:

int *n1

n1声明为指针为整数。

答案 2 :(得分:1)

您的输入功能有几个问题:

void input(int *n1, int *n2)
{
    int a, b;   

    printf("Enter first number: \n");
    scanf("%d", &n1);

这很可能是导致崩溃的根本原因。函数参数n1 已经指向int的指针,它包含您要在main中写入的内容的地址; &n1是指向int指针的指针,并为您提供n1函数参数的地址。因此,不是将整数值写入n1 指向的值,而是将整数值写入n1本身。

然后,当您尝试取消引用n1指针并指定它指向的内容时

*n1 = a;

你最终试图访问无效的地址,因此崩溃了。您需要将输入行更改为以下内容:

    scanf( "%d", n1 ); // no & operator on n1

n2的输入存在同样的问题;你不需要&,因为n2已经是指针类型了。

然后我们有了这个:

    *n1 = a;
    *n2 = b;

此时ab包含哪些内容?无论是什么,假设您修复了上面的代码,您将覆盖已经阅读的任何内容*n1*n2。要么摆脱这些行(以及ab的声明),要么使用ab作为scanf调用的目标:

    scanf( "%d", &a ); // a is not already a pointer, need the & operator
    ...
    scanf( "%d", &b ); // same as above
    ...
    *n1 = a;
    *n2 = b;
}

答案 3 :(得分:-4)

scanf(&#34;%c&#34;,&amp; opt);避免这样将char作为输入.. 而是使用 scanf(&#34;%s&#34;,&amp; opt); 来获取char输入。

我认为这个答案很有帮助。