C - Scanf и Printf выполняются не по порядку, и я не уверен, почему - PullRequest
0 голосов
/ 22 января 2019

У меня есть проблема, когда мне нужно написать программу, управляемую меню, используя указатели функций на C. Пользователь выбирает вариант 1-3, и сложение выполняется, если response = 1, вычитать, если response = 2, умножать, если response = 3.

Первый проход идеален, но как только я повторяю цикл и пытаюсь выполнить второй расчет, он ищет выбор И первое число, прежде чем отобразит, какой выбор вы сделали.

Математика в каждой функции работает, передавая переменные, только операторы printf и scanf вышли из строя после первого запуска.

(Существуют функции вычитания и умножения, они точно такие же, за исключением того, что вместо оператора "+" есть операторы "-" и "*" соответственно.)

Я искал проблему, подобную этой, и пробовал команды fflush и setvbuf, они не работали.

void addition(int num1, int num2);
void subtraction(int num1, int num2);
void multiplication(int num1, int num2);

int main(void) {
    void(*m[3])(int, int) = { addition, subtraction, multiplication };

    size_t choice;
    int num1, num2;
    printf_s("Would like to add, subtract, or multiply?\nType 1 for 
addition, 2 for subtraction, 3 for multiplication.\n");
    scanf_s("%d", &choice);
    printf_s("what two numbers would you like to work with?\n");
    scanf_s("%d", &num1);
    scanf_s("%d", &num2);
        if (choice >= 1 && choice <= 3) {
        (*m[choice - 1])(num1, num2);
        while (choice >= 1 && choice <= 3) {

            printf_s("Would like to add, subtract, or multiply?\nType 1 
for addition, 2 for subtraction, 3 for multiplication.\n");
            choice = 0;
            scanf_s("%d\n", &choice);
            printf_s("what two numbers would you like to work with?\n");
            scanf_s("%d", &num1);
            scanf_s("%d", &num2);
            (*m[choice - 1])(num1, num2);
        }
        printf("execution complete");
    }
    return 0;
}

void addition(int num1, int num2) {
    int i = 0;
    i = num1 + num2;
    printf("%d + %d = %d\n", num1, num2, i);
    }

Если я введу следующее: 1 2 3, 2 3 1, я ожидаю, что результат будет

"1"

"What two numbers would you like to work with?"

"2"

"3" 
"2+3=5" 
"would you like to add, subtract, or multiply?" 
"Type 1 (...) for multiplication" 
"2" 
"what two numbers (...)" 
"3" 
"1" 
"3-1 =2"

Однако я получаю это:

"1" 
"What two numbers would you like to work with?"
"2" 
"3" 
"2+3=5" 
"would you like to add, subtract, or multiply?" 
"Type 1 (...) for multiplication"
"2" 
"3" 
"what two numbers (...)" 
"1" 
"3-1 =2"

Как видите, математика верна, но во второй раз ей потребовалось 2 числа, прежде чем она запросит 2 числа. Я не понимаю, как это возможно, так как перед выполнением следующего оператора printf сканируется только одна переменная. Несмотря на то, что умноженное на «3» значение было сохранено в num1, оно сканировалось до printf, даже если оператор указан после printf, поэтому это не должно быть возможным. Я так растерялся!

Ответы [ 4 ]

0 голосов
/ 22 января 2019

Я бы сделал это так:

int main(void) {
    void(*m[3])(int, int) = { addition, subtraction, multiplication };
    size_t choice = 1;
    int num1, num2;
    while (choice >= 1 && choice <= 3) {
        printf_s("Would like to add, subtract, or multiply?\nType 1 for addition, 2 for subtraction, 3 for multiplication.\n");
        choice = 0;
        scanf_s("%d", &choice);
        printf_s("what two numbers would you like to work with?\n");
        scanf_s("%d", &num1);
        scanf_s("%d", &num2);
        (*m[choice - 1])(num1, num2);
    }
    return 0;
}

Ваша проблема была - у вас был scanf_s("%d\n", &choice); - вы должны делать это без \ n - scanf_s("%d", &choice); и цикл, который вы можете сделать намного проще. Удалите if и установите выбор 1.

0 голосов
/ 22 января 2019

почему этот длинный и сложный код?

просто замените

printf_s("Would like to add, subtract, or multiply?\nType 1 for addition, 2 for subtraction, 3 for multiplication.\n");
scanf_s("%d", &choice);
printf_s("what two numbers would you like to work with?\n");
scanf_s("%d", &num1);
scanf_s("%d", &num2);
    if (choice >= 1 && choice <= 3) {
    (*m[choice - 1])(num1, num2);
    while (choice >= 1 && choice <= 3) {

        printf_s("Would like to add, subtract, or multiply?\nType 1 for addition, 2 for subtraction, 3 for multiplication.\n");
        choice = 0;
        scanf_s("%d\n", &choice);
        printf_s("what two numbers would you like to work with?\n");
        scanf_s("%d", &num1);
        scanf_s("%d", &num2);
        (*m[choice - 1])(num1, num2);
    }
    printf("execution complete");
}

на

for (;;) {
  printf("Would like to add, subtract, or multiply?\nType 1 for addition, 2 for subtraction, 3 for multiplication.\n");
  if (scanf("%d", &choice) != 1) {
    puts("abort");
    break;
  }

  if ((choice < 1) || (choice > 3))
    break;

  printf("what two numbers would you like to work with?\n");
  if (scanf("%d %d", &num1, &num2) != 2) {
    puts("abort");
    break;
  }
  (*m[choice - 1])(num1, num2);
}
printf("execution complete");
0 голосов
/ 22 января 2019

Удалить '\n'.

scanf_s("%d\n"... не вернется до тех пор, пока после номера не будет введен непустой пробел.

// scanf_s("%d\n", &choice);
scanf_s("%d", &choice);

Могут существовать и другие проблемы.

0 голосов
/ 22 января 2019

Используйте scanf_s("%d\n",&var);, делая так, чтобы 'scanf' считывал символ новой строки (ввод), вставленный, когда вы 'фиксировали' ввод данных. В противном случае этот символ будет перенаправлен в поток и повлияет на следующее сканирование и, будучи этим символом вводом, заставит ваш код двигаться дальше.

...