Хобрук: Ваш путь к мастерству в программировании

Как предотвратить бесконечный цикл с ошибкой scanf

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

#include <stdio.h>
#include <stdlib.h>
#define amtPaid 1
#define SENTINAL -1
int quarters(int numChange);
int dimes(int numChange);
int nickels(int numChange);
int pennies(int numChange);

int main(void)
{
    double amtDue = 0; // how much is paid


while(1){
    printf("\nPlease enter the price less than 1 dollar: ");
    scanf(" %lg", &amtDue);
    int changeReturn = (amtPaid - amtDue) * 100 + 0.5; // convert decimal to whole number
    int updated = 0;    // remaining change after amt of change
    int numberQuarters = quarters(changeReturn); // number of quarters needed

   if(changeReturn >= 0 && changeReturn <= 100){ // if changereturn  is between 0 and 100 execute code

        printf("\nNice!");
        printf("\nWe owe you %i cents" , changeReturn);
        if(numberQuarters >= 0){    // get and print number of quarters
            printf("\nQuarters: %i", numberQuarters);
            updated = changeReturn % 25;
        }
        if(dimes(updated) >= 0){ // get and print number of dimes
            printf("\nDimes: %i", dimes(updated));
            updated = updated % 10;
        }
        if(nickels(updated)>= 0){ // get and print number of nickels
            printf("\nNickels: %i", nickels(updated));
            updated = updated % 5;
        }
        if(pennies(updated) >= 0){ // get and print number pennies
            printf("\nPennies: %i", pennies(updated));
        }

    }

    else if(amtDue == SENTINAL){
        break;
    }

    else {
        printf("That does not make sense to me. please type a valid number");
    }

    printf("\n %g", amtDue);

}
return 0;
}

int quarters(int numChange){
    int numQuarters = 0;

    numQuarters = numChange / 25;

    return numQuarters;
}
int dimes(int numChange){
    int numDimes = 0;

    numDimes = numChange / 10;

    return numDimes;
}
int nickels(numChange){
    int numNickels = 0;

    numNickels = numChange / 5;

    return numNickels;
}
int pennies(numChange){

    return numChange;
}
15.09.2015

Ответы:


1

В случае предоставления недопустимого значения, отличного от ожидаемого значения спецификатора формата с scanf(), scanf() завершится ошибкой, и недопустимое значение остается во входном буфере, обеспечивая поток к следующему scanf(), только чтобы вызвать последовательные сбои. В этом случае вам нужно очистить буфер ввода, прежде чем переходить к следующему вводу. Вы можете использовать что-то вроде

  1. проверьте возвращаемое значение scanf()
  2. В случае сбоя используйте while( getchar() != '\n' ); для очистки входного буфера.

При этом int nickels(numChange) теперь недействительно в c (начиная с C99). Вы должны сделать это как int явно.

15.09.2015

2

Вместо использования scanf(" %lg", &amtDue); получайте пользовательский ввод в виде строки, чтобы вы могли выполнить правильную проверку.

char input[500];
fgets(input, 500, stdin);

// do some input checking

double val = atof(input);

// do calculations on the number

Чтобы проверить, есть все виды функций, которые помогут вам в ctype.h, одна из которых может показаться вам интересной, это isalpha.
<час>

Ссылки на руководство:

  • fgets
  • atof преобразует строку в double
  • atoi преобразует строку в целое число
  • isalpha
15.09.2015
Новые материалы

Dall-E 2: недавние исследования показывают недостатки в искусстве, созданном искусственным интеллектом
DALL-E 2 — это всеобщее внимание в индустрии искусственного интеллекта. Люди в списке ожидания пытаются заполучить продукт. Что это означает для развития креативной индустрии? О применении ИИ в..

«Очень простой» эволюционный подход к обучению с подкреплением
В прошлом семестре я посетил лекцию по обучению с подкреплением (RL) в моем университете. Честно говоря, я присоединился к нему официально, но я редко ходил на лекции, потому что в целом я нахожу..

Освоение информационного поиска: создание интеллектуальных поисковых систем (глава 1)
Глава 1. Поиск по ключевым словам: основы информационного поиска Справочная глава: «Оценка моделей поиска информации: подробное руководство по показателям производительности » Глава 1: «Поиск..

Фишинг — Упаковано и зашифровано
Будучи старшим ИТ-специалистом в небольшой фирме, я могу делать много разных вещей. Одна из этих вещей: специалист по кибербезопасности. Мне нравится это делать, потому что в настоящее время я..

ВЫ РЕГРЕСС ЭТО?
Чтобы понять, когда использовать регрессионный анализ, мы должны сначала понять, что именно он делает. Вот простой ответ, который появляется, когда вы используете Google: Регрессионный..

Не зря же это называют интеллектом
Стек — C#, Oracle Опыт — 4 года Работа — Разведывательный корпус Мне пора служить Может быть, я немного приукрашиваю себя, но там, где я живу, есть обязательная военная служба на 3..

LeetCode Проблема 41. Первый пропущенный положительный результат
LeetCode Проблема 41. Первый пропущенный положительный результат Учитывая несортированный массив целых чисел, найдите наименьшее пропущенное положительное целое число. Пример 1: Input:..