L_Stud
L_Stud

Reputation: 43

How to prevent an infinite loop with scanf failure

The Code is supposed to make change for a dollar and works fine. but the professor says that he will be enter random numbers along with letters. It works fine with numbers but when a letter is entered an infinite loop will occur any suggestions?

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

Upvotes: 2

Views: 2378

Answers (2)

Enzo Ferber
Enzo Ferber

Reputation: 3094

Instead of using scanf(" %lg", &amtDue);, get the user input as a string, so you can do proper checking.

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

// do some input checking

double val = atof(input);

// do calculations on the number

To check, there's all kinds of functions to help you in ctype.h, one that you might find interesting is isalpha.


Manual References:

Upvotes: 0

Sourav Ghosh
Sourav Ghosh

Reputation: 134286

In case an inappropriate value is supplied other than the expected value of the format specifier with scanf(), the scanf() will fail and the inappropriate value will remain in the input buffer, providing the feed to next scanf(), only to cause successive failures. In that case, you need to clean up the input buffer before going for next input. You can use something like

  1. check the return value of scanf()
  2. In case of failure, use while( getchar() != '\n' ); to clean the input buffer.

That said, int nickels(numChange) is now invalid in c (C99 onwards). You have to make it as int explicitly.

Upvotes: 4

Related Questions