Nano Hash - криптовалюты, майнинг, программирование

C - Scanf и Printf выполняются не по порядку, и я не уверен, почему

У меня есть проблема, когда мне нужно написать программу, управляемую меню, с использованием указателей функций в C. Пользователь выбирает вариант 1-3, и выполняется сложение, если ответ = 1, вычитание, если ответ = 2, умножение, если ответ = 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, поэтому это невозможно. Я весьма озадачен!


  • Рассмотрите возможность использования некоторых разрывов строк / новых строк в вашем вопросе (код и проза), чтобы улучшить читаемость; особенно в ожидаемом выходе. 22.01.2019
  • size_t choice; scanf_s("%d", &choice); не совпадает. Попробуйте int choice;. 22.01.2019
  • Удалите лишние "\n" в одном из сканов. 22.01.2019
  • ... этот scanf_s("%d\n", &choice); 22.01.2019
  • Вы никогда не проверяете возвращаемое значение из scanf_s(), поэтому вы никогда не знаете, что оно читает. Также обратите внимание, что так называемые безопасные функции, такие как scanf_s(), ничуть не безопаснее, чем так называемые небезопасные функции (они не устарели — они требуются по стандарту C...) и все, что вы на самом деле делаете, используя их, — это делает ваш код непереносимым и зависящим от платформы. 22.01.2019
  • Кроме того: было бы довольно легко изменить код, чтобы вам не приходилось повторять подсказку и ввод кода. 22.01.2019

Ответы:


1

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

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

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

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

22.01.2019
  • Спасибо, я столько раз просматривал эту строку, а лишний \n даже не щелкнул. Хорошего дня. 22.01.2019
  • как можно выбрать тот ответ, который почти ничего не решает? Другие проблемы могут существовать слишком, лол, конечно 22.01.2019
  • @bruno Code имеет множество недостатков. Я вижу по крайней мере 5. Если OP хочет общий обзор, просмотр кода - хорошее место для этого. 22.01.2019
  • @Бруно да. С ответом Чукса я понял свою ошибку и смог ее решить, вы просто написали свой собственный код, и я бы никогда не узнал об этой проблеме. 22.01.2019

  • 2

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

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

    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");
    }
    

    by

    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");
    
    22.01.2019
  • @AndrewHenle, вот почему я только что отредактировал свой ответ ;-) 22.01.2019

  • 3

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

    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.

    22.01.2019

    4

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

    22.01.2019
  • Да делал, исправил. . 23.01.2019
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..