C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 07-04-2009, 08:52 AM   #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???
alekbabich is offline   Reply With Quote
Old 07-04-2009, 08:54 AM   #2
Registered User
 
Join Date: Jul 2009
Posts: 8
please ignore the printf("invalid") after the first printf("invalid entry, try again");
alekbabich is offline   Reply With Quote
Old 07-04-2009, 09:37 AM   #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;
}
WatchTower is offline   Reply With Quote
Old 07-04-2009, 09:53 AM   #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.
alekbabich is offline   Reply With Quote
Old 07-04-2009, 10:38 AM   #5
Registered User
 
Join Date: Oct 2008
Location: TX
Posts: 1,262
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.
itCbitC is offline   Reply With Quote
Old 07-04-2009, 10:51 AM   #6
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,352
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.
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
laserlight is offline   Reply With Quote
Old 07-04-2009, 11:41 AM   #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
alekbabich is offline   Reply With Quote
Old 07-04-2009, 11:55 AM   #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
Bladactania is offline   Reply With Quote
Old 07-04-2009, 12:04 PM   #9
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,352
By the way, this:
Code:
fgets(line, sizeof(line)-1, stdin);
should be:
Code:
fgets(line, sizeof(line), stdin);
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
laserlight is offline   Reply With Quote
Old 07-04-2009, 06:03 PM   #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?
alekbabich is offline   Reply With Quote
Old 07-04-2009, 06:32 PM   #11
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
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.
matsp is offline   Reply With Quote
Old 07-04-2009, 07:44 PM   #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.
strickyc is offline   Reply With Quote
Old 07-05-2009, 06:21 AM   #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.
alekbabich is offline   Reply With Quote
Old 07-05-2009, 07:13 AM   #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);
alekbabich is offline   Reply With Quote
Old 07-05-2009, 04:04 PM   #15
Registered User
 
Join Date: Oct 2008
Location: TX
Posts: 1,262
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.
itCbitC is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
C keep a loop going whilst program continues on fortune2k C Programming 6 03-11-2009 08:44 AM
Printing "shapes" based on character lines and number of line inputs matt_570 C++ Programming 11 10-07-2008 06:19 PM
Using While Loop to write a program Cyberman86 C++ Programming 2 09-16-2008 12:52 PM
Unexplained "unhandled exception" ulillillia C Programming 6 04-19-2007 11:19 AM
UNICODE and GET_STATE Registered C++ Programming 1 07-15-2002 03:23 PM


All times are GMT -6. The time now is 05:52 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22