954,499 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

floating point/character

I do not know if this has ever been asked in C before but

I have a floating point variable like this:

while (fCost <= 0.0)
 	    {
            printf("\n\tKudler Fine Foods 'Sales Tax Calculator'\t\n");
            printf("\nPlease enter your sub-total:\n"); //allows customer to enter sub-total
            scanf("\n%f", &fCost);
            }


note the variable was named as a floating point earlier

When I type in c or m or any other letter and not a number I go into an infinite loop

now the question

How to I get the loop to repeat and not accept a character so I can prevent the infinite loop?

moogle1979
Newbie Poster
4 posts since Jun 2008
Reputation Points: 10
Solved Threads: 0
 

>How to I get the loop to repeat and not accept a character so I can prevent the infinite loop?
By ditching the use of scanf() to read input form user.
Here's the start of alternatives on how to read a floating point from user.

Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218
 
I do not know if this has ever been asked in C before but

only about a million times :P

other than that, the link Aia gives is pretty solid. anything i might add would just be pedantry.

jephthah
Posting Maven
2,587 posts since Feb 2008
Reputation Points: 2,143
Solved Threads: 179
 

Thank you both, I now just need to understand it

moogle1979
Newbie Poster
4 posts since Jun 2008
Reputation Points: 10
Solved Threads: 0
 

on the one hand, i like the compactness of Sinkula's code (i sometimes code like that), but on the other hand, it doesnt lend itself very well to readability for people not used to the style

int mygetd(double *result)
{
   char buff [ 32 ]; /* modify as needed */
   return fgets(buff, sizeof buff, stdin) && sscanf(buff, "%lf", result) == 1;
}

It might help you if we break out the "return" statement a little bit for readability.

So here is an example of his code broken out to an extreme degree. I normally wouldn't write such tedious code for a simple function, but this might make it more clear as to what the operations grouped in his "return" statement are actually doing.

int mygetd(double *result)
{
   char buff [ 32 ]; /* modify as needed */
   numBytesRead = 0;
   isValidValue = 0;

   numBytesRead = fgets(buff, sizeof buff, stdin) 
   if (numBytesRead>0)  // format value, pass back as "result"
      isValidValue = sscanf(buff, "%lf", result);

   if (isValidValue == 1) 
      return 1;  // value entered is good
   else
      return 0; // no valid value found
}

To understand how his combined return statement works, you can follow it by the C operators' order of precedence...

first the "fgets()" function is performed, if it evaluates as TRUE, then the "scanf(...) ==1" function is subsequently evaluated (note, the == 1 is redundant). if it also evaluates as TRUE, the entire function returns TRUE (1), and the variable "result" is passed back with correct value.

But if the "fgets()" function evaluates as false, the entire routine immediately returns with FALSE (0) and the "scanf()" function is not even performed, so the variable "result" is left unmodified.

Or if "scanf()==1" evaluates as false, the entire routine likewise returns FALSE and "result" is either unmodified or undefined (i forget which).


.

jephthah
Posting Maven
2,587 posts since Feb 2008
Reputation Points: 2,143
Solved Threads: 179
 

It might help you if we break out the "return" statement a little bit for readability.

So here is an example of his code broken out to an extreme degree. I normally wouldn't write such tedious code for a simple function, but this might make it more clear as to what the operations grouped in his "return" statement are actually doing.

int mygetd(double *result)
{
   char buff [ 32 ]; /* modify as needed */
   numBytesRead = 0;
   isValidValue = 0;

   numBytesRead = fgets(buff, sizeof buff, stdin) 
   if (numBytesRead>0)  // format value, pass back as "result"
      isValidValue = sscanf(buff, "%lf", result);

   if (isValidValue == 1) 
      return 1;  // value entered is good
   else
      return 0; // no valid value found
}

To understand how his combined return statement works, you can follow it by the C operators' order of precedence...

first the "fgets()" function is performed, if it evaluates as TRUE, then the "scanf(...) ==1" function is subsequently evaluated (note, the == 1 is redundant). if it also evaluates as TRUE, the entire function returns TRUE (1), and the variable "result" is passed back with correct value.

But if the "fgets()" function evaluates as false, the entire routine immediately returns with FALSE (0) and the "scanf()" function is not even performed, so the variable "result" is left unmodified.

Or if "scanf()==1" evaluates as false, the entire routine likewise returns FALSE and "result" is either unmodified or undefined (i forget which).

.

The fgets function returns a pointer (not a count of characters), and if it fails it will be a null pointer. The first implicit check is whether or not fgets returned a non-null pointer, indicating success.

The sscanf function returns the number of input items assigned. This could be EOF, 0, or 1 for this case; a return value of 1 will indicated success, other results would indicate failure, so it is a check for success. The check for equality with 1 is not redundant, because EOF would be a nonzero value.

So it reads something like, "If you successfully obtained input text and you successfully converted that input text into a number, then return true. If anything fails, return false."

Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 

good points -- i stand corrected.

one day i'll learn about relying on "memory"

.

jephthah
Posting Maven
2,587 posts since Feb 2008
Reputation Points: 2,143
Solved Threads: 179
 

Yesterday as I was going over the section on fgets I was researching it up and ran across someone that used the following code and said it worked

//User Requirements
            printf("\nWelcome to Kudler Fine Foods,\n\nWe hope you enjoyed your shopping experience.\n");
            printf("\n\n\n\tPlease Enter your Subtotal: $");
            iResponse = scanf("%f", &fCost);
            
            //validity check
            while (fCost < fCheck || iResponse != 1){
	    fflush(stdin);
	    printf("\n\tPlease Re-enter your Subtotal: $");
	    iResponse = scanf("%f", &fCost);
	    }//end while loop

Note:I hope this code wraps up in the codebox, sorryif it does not

Someone came behind them and said fflush does not always work and did not explain why
Is there a big difference between fflush and fgets?

moogle1979
Newbie Poster
4 posts since Jun 2008
Reputation Points: 10
Solved Threads: 0
 

The issue is fflush(stdin) . http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1052863818&id=1043284351


[edit]The earlier snippet ended up being a part of User Input: Strings and Numbers [C] . There I'd gone into various details a little deeper. At one time that tutorial ended with a discussion of the fflush(stdin) issue which always seems to follow along with these questions. For whatever reason, the powers that be elided that portion.

Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 

(1) fflush and fgets are two totally separate things, and completely independent of each other.

(2) fflush is only meaningful for "stdout", as im sure Dave's link explains.

(3) the code you have that someone "said it worked" will not work any better than your original code. if you enter an invalid input, it will still blow up on you.

.

jephthah
Posting Maven
2,587 posts since Feb 2008
Reputation Points: 2,143
Solved Threads: 179
 

Thank you both

moogle1979
Newbie Poster
4 posts since Jun 2008
Reputation Points: 10
Solved Threads: 0
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You