2015-09-25 2 views
1

Я начинаю программировать, и мне нужна помощь в моем коде. Предполагается, что это калькулятор с 6 функциями, включая основной. Четыре для операций и один для ввода двух чисел. Он сбрасывается, как только я ввожу второй ввод для номера. Кроме того, у меня возникла проблема с возвратом значений из функции input() в основную функцию для выполнения операций. Может быть, это что-то связано со сканированием на выбор?Сбой кода после вызова scanf

#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; 
} 

Я также делаю это правильно?

+0

'зсапЕ ("% D", &n1);' -> 'Scanf ("% d", &a); ',' scanf ("% d", &n2); '->' scanf ("% d", &b); ' – BLUEPIXY

ответ

2

Проблема заключается в input:

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

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

%d спецификатор формата ожидает int * аргумент. С n1 и n2 уже находятся int *, то есть &n1 и &n2 имеют тип int **. Это вызывает ошибку сегментации.

Чтобы это исправить, просто передать в n1 и n2:

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

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

    getchar(); 
} 

Вы заметите, что a и b не требуется, если вы сделаете это. Также обратите внимание на вызов getchar(), чтобы использовать новую строку во входном буфере. Если вы этого не сделаете, новая линия будет поднята scanf в main, и инструкция switch не будет введена.

Кроме того, в ваших четырех математических функциях не указывается тип возврата. Поскольку прототипы для этой функции объявляют их как возвращающие int, а потому, что int - это тип возвращаемого по умолчанию для функции, ему удается работать. Однако вы всегда должны указывать тип возврата.

+1

Вы забыли исправить правильную версию. – NobodyNada

+0

@NobodyNada Спасибо. Исправлена. – dbush

+0

Hmmm ... Как вы указываете тип возврата? О, и для чего же звездочкой? – fixotherm

1

scanf принимает указатели на целые числа, но вы неправильно передаете указатели указателям на целые числа.

Fix:

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

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

и вам не нужно a и b, значения от входа непосредственно записываются в точках, что указатель на. Вы должны также прочитать '\n' от входного потока до звонка до scanf("%c", &opt); в main функция. В противном случае вы прочтете новую строку, тогда как вы ожидаете прочитать символ опции.


Чтобы решить свой вопрос в комментариях:

int *n1 

объявляет n1 быть указателя в целом.

+0

Yaayyy !!: D Спасибо :) Это сработало. Как вы это делаете ? Oo Скорее, что означает * перед n1 и n2? – fixotherm

+0

Добро пожаловать, сэр. – 4pie0

+0

@fixotherm * n Указывает на то, что вы используете значение, указанное в ячейке памяти, обозначенной символом n. В этом случае '* n1 знак равно a' означает, что 'n1' укажет на некоторую часть памяти, внутри которой находится значение' a' –

-4

scanf ("% c", & opt); избегайте этого, чтобы получить char как вход. скорее использовать scanf ("% s", & opt);, чтобы получить входы char.

Я думаю, что этот ответ полезен.

+0

'% s' сканирует строку. Он хочет сканировать символ. Кроме того, это не отвечает на вопрос, почему 'input()' сбой. – NobodyNada

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; 

Что a и b содержат в этот момент? Как бы то ни было, если вы исправите код выше, вы перепишете все, что вы уже прочитали, в *n1 и *n2. Либо избавиться от этих линий (и декларации для a и b), или использовать a и b в качестве мишеней для Scanf вызовов:

scanf("%d", &a); // a is not already a pointer, need the & operator 
    ... 
    scanf("%d", &b); // same as above 
    ... 
    *n1 = a; 
    *n2 = b; 
} 
Смежные вопросы