Thread: Program thrown into loop when character entered instead of flaot

  1. #1
    Registered User
    Join Date
    Jul 2009
    Posts
    8

    Program thrown into loop when character entered instead of flaot

    I am trying to get my program to check the validity of a entry. When the user enteres a character rather than a float, I want the program to ask them to check their entry and enter it again. I have tried the getchar(), and isdigit commands, but can't figure it out. I am completely new to this. Right now when the user enters a character rather than a float, it throws the program into a continuous loop.


    Code:
    #include <system.h>
    #include <stdio.h>
    #include <ctype.h>
    main()
    {
    
    //   Variable declarations and initializations
    	int iResponse = 0;
    	float fDel_Mar_Tax = 7.25;
    	float fEncinitas_Tax = 7.5;
    	float fLa_Jolla_Tax = 7.75;
    	float fPurchase_Amount = 0.0;
    	
    //   Program Header
    	printf("\n\t\t             Tax Calculator 2 by Aleksandr Babich\n\n\n");
    
    //   Enter purchase amount and verify purchase amount
    	do { // do-while loop start
    	printf("\n\nEnter the total purchase amount: $");
    	scanf("%f", &fPurchase_Amount);	
    	if (fPurchase_Amount <= 0.0)
    		printf("\nInvalid entry, try again");
    		printf("invalid");
    	} //end do-while loop	
    	while (fPurchase_Amount <= 0.0);
    	printf("\n\nTotal purchase is $ %5.2f", fPurchase_Amount);
    	
    
    	do { //start of do-while loop
    
    // Store selection
    	printf("\n\n1\tDel Mar\n");
    	printf("2\tEncinitas\n");
    	printf("3\tLa Jolla\n");
    	printf("\nPlease select your shopping location (1-3): ");
    	scanf("%d", &iResponse);
    	
    // User Store selection validity
    	if (iResponse <= 0 || iResponse >= 4) 
    		printf("\n\nInvalid entry - Please try again\n\n");
    	else
    		printf("\n\n\t\t\t\t   TOTALS");
    	
    
    
    	
    	switch (iResponse){ 
    
    	case 1:
    	printf("\n ------------------------------------------------------------------------------\n");
    	printf("\n\t\tTotal purchase amoune is $%5.2f\n",fPurchase_Amount);
    	printf("\n\t\tThe total tax on your purchaes is $%5.2f\n", fDel_Mar_Tax/100.0 * fPurchase_Amount);
    	printf("\n\t\tYour total amount due is $%5.2f\n", fPurchase_Amount + (fDel_Mar_Tax/100.0 * fPurchase_Amount));
    	printf("\n\t    Thank you for shopping at Kuddler Fine Foods Del Mar");
    	printf("\n ------------------------------------------------------------------------------\n");
    	break;
    	case 2:
    	printf("\n ------------------------------------------------------------------------------\n");
    	printf("\n\t\tTotal purchase amoune is $%5.2f\n",fPurchase_Amount);
    	printf("\n\t\tThe total tax on your purchase is $%5.2f\n", fEncinitas_Tax/100.0 * fPurchase_Amount);
    	printf("\n\t\tYour total amount due is $%5.2f\n", fPurchase_Amount + (fEncinitas_Tax/100.0 * fPurchase_Amount));
    	printf("\n\t    Thank you for shopping at Kuddler Fine Foods Encinitas");
    	printf("\n ------------------------------------------------------------------------------\n");
    	break;
    	case 3:
    	printf("\n ------------------------------------------------------------------------------\n");
    	printf("\n\t\tTotal purchase amoune is $%5.2f\n",fPurchase_Amount);
    	printf("\n\t\tThe total tax on your purchase is $%5.2f\n", fLa_Jolla_Tax/100.0 * fPurchase_Amount);
    	printf("\n\t\tYour total amount due is $%5.2f\n", fPurchase_Amount + (fLa_Jolla_Tax/100.0 * fPurchase_Amount));
    	printf("\n\t    Thank you for shopping at Kuddler Fine Foods La Jolla");
    	printf("\n ------------------------------------------------------------------------------\n\n\n\n");
    	
    	} //end switch
    	
    	} while (iResponse <= 0 || iResponse >= 4); 
    
    
    	
    //Initiate a stop and wait for user input to continue
    	printf("\nPress any key to continue...\n");
    	getch();
    
    
    }//end main
    any ideas???

  2. #2
    Registered User
    Join Date
    Jul 2009
    Posts
    8
    please ignore the printf("invalid") after the first printf("invalid entry, try again");

  3. #3
    Registered User
    Join Date
    Jul 2009
    Posts
    40
    Maybe you could pick-up some idea with this code.

    Code:
    #include <ctype.h>
    #include <stdio.h>
    #include <conio.h>
    
    int main()
    {
        char input;
    
        while( 1 )
        {
            input = getch();
            if( isdigit( input ) )
              printf( "\n%c is a digit", input );
            else if( isalpha( input ) )
              printf( "\n%c is an alpha", input );
            else if( 27 == ( int ) input ) //press escape to exit
              break;
        }
    
        return 0;
    }

  4. #4
    Registered User
    Join Date
    Jul 2009
    Posts
    8
    Thanks,

    I'll play with it, I entered it in to start and it still throws the program in a continuous loop if a character is entered instead of a number. I'll play with your suggestions. Thanks.

  5. #5
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    An alternative to scanf() would be to use a combination of fgets() and strtod(), as in
    Code:
    char line[BUFSIZ];
    double fPurchase_Amount = 0.0;
    fgets(line, sizeof(line)-1, stdin);
    fPurchase_Amount = strtod(line, NULL);
    ...
    Caveat with this approach is that input errors like 123q will be parsed correctly so that fPurchase_Amount has 123.0 in it.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itCbitC
    Caveat with this approach is that input errors like 123q will be parsed correctly so that fPurchase_Amount has 123.0 in it.
    That said, you can check for such an input error by passing a non-null pointer as the second argument to strtod() and then checking to see that it points to the first element of an empty string after the conversion.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Jul 2009
    Posts
    8
    char line[BUFSIZ];
    double fPurchase_Amount = 0.0;
    fgets(line, sizeof(line)-1, stdin);
    fPurchase_Amount = strtod(line, NULL);
    ...

    I'm new to the whole C programming, can you explain this code line by line?

    Thanks

  8. #8
    Registered User
    Join Date
    Feb 2009
    Posts
    278
    Code:
    char line[BUFSIZ];  // Creates a character array BUFSIZE characters long
    double fPurchase_Amount = 0.0; // Creates a float variable and initializes to 0.0
    fgets(line, sizeof(line)-1, stdin);  // sizeof(line) - 1 is the number of characters that can fit into line.  So fgets gets that many characters from stdin (the keyboard) and puts them into the variable line
    fPurchase_Amount = strtod(line, NULL); // converts the character array line into a double value and assigns this value to fPurchase_Amount

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    By the way, this:
    Code:
    fgets(line, sizeof(line)-1, stdin);
    should be:
    Code:
    fgets(line, sizeof(line), stdin);
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Jul 2009
    Posts
    8
    Maybe I'm overcomplicating the problem. I simply only want to allow numric entries whre I ask the user to enter something. Does "C" have an easy way of doing this?

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by alekbabich View Post
    Maybe I'm overcomplicating the problem. I simply only want to allow numric entries whre I ask the user to enter something. Does "C" have an easy way of doing this?
    Well, no, there is no (standard, simple and generic) way to tell "C" to "accept only numbers here".
    You can check if scanf() [and it's siblings] accepted the input correctly by checking the return value. But scanf() itself will leave anything unacceptable for the input you requested [e.g. letter instead of numbers when you asked for a number] in the input buffer - this is the reason for your loop - you need to clear out any unwanted input.

    So you either need to try the to input using scanf(), report error and "clean up any mess" if the input wasn't OK. Alternative 2: you use a different input method that is guaranteed to READ the input, and then try to interpret the input, and report errors if it's no good. But you don't have to clean anything up, because it was already read in.

    The second solution is the above fgets() and strtod() or sscanf(), is a good idea - it reads a line of "anything", and then you use a second function to convert and check the input. That way, nothing ever gets "left behind" to cause a problem later on.

    The third option is called "tokenizing". In this case you read a character at a time, with rules as to what goes where and what can be accepted and what to report errors with (and what to look for to recover/clean up), usually with knowledge as to what you expect. This is more complicated, but give the programmer full flexibility in interpreting/controlling the input. I think you are a bit too much of a novice for this method.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Registered User
    Join Date
    Apr 2009
    Posts
    41
    isdigit()

    i.e if(isdigit(variable))
    {
    do this
    }
    else
    getchar();
    Last edited by strickyc; 07-04-2009 at 07:49 PM.

  13. #13
    Registered User
    Join Date
    Jul 2009
    Posts
    8
    Thanks,

    When I woke up this morning, thats what I was thinking (isdigit). Then I logged on here and saw your comment, I entered it and it works well. Thanks.

  14. #14
    Registered User
    Join Date
    Jul 2009
    Posts
    8
    Can you impose a time limit on a command like getchar() ???

    I got the program to stop and not loop if the user enters a character rather than a number, but now the program stops and waits for the user to hit a key when they enter a number.
    Code:
    //   Enter purchase amount and verify purchase amount
    	do { // do-while loop start
    		printf("\n\nEnter the total purchase amount: $");
    		scanf("%f", &fPurchase_Amount);
    	if (fPurchase_Amount <= 0.0)
    		printf("\nYou did not enter a valid number, please try again");
    	if (isdigit(fPurchase_Amount));
    	else
    		getchar();
    	} //end do-while loop	
    	while (fPurchase_Amount <= 0.0);

  15. #15
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by laserlight View Post
    That said, you can check for such an input error by passing a non-null pointer as the second argument to strtod() and then checking to see that it points to the first element of an empty string after the conversion.
    Yep! the second (non-NULL) argument to strtod() can be used to check if there are any unwanted characters left behind.
    The caveat was relevant only to the code snippet I had provided but the o/p will do well to use a non-NULL 2nd argument.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C keep a loop going whilst program continues on
    By fortune2k in forum C Programming
    Replies: 6
    Last Post: 03-11-2009, 08:44 AM
  2. Replies: 11
    Last Post: 10-07-2008, 06:19 PM
  3. Using While Loop to write a program
    By Cyberman86 in forum C++ Programming
    Replies: 2
    Last Post: 09-16-2008, 12:52 PM
  4. Unexplained "unhandled exception"
    By ulillillia in forum C Programming
    Replies: 6
    Last Post: 04-19-2007, 11:19 AM
  5. UNICODE and GET_STATE
    By Registered in forum C++ Programming
    Replies: 1
    Last Post: 07-15-2002, 03:23 PM