1

How can I ensure that my program checks that a user enters a valid floating point value? I tried GetFloat but that only seems to return retry in the event that a user enters a non numeric value. If a user enters, for example, 1234 instead of 12.34, GetFloat isn't prompting for a retry and the rounding and casting part of my code becomes incorrect.

Any nudge in the right direction would be great. No code please, I don't want to cheat, just learn.

1
  • Do you mean differentiating between user input as floating point number and an integer? – sinister Oct 1 '14 at 15:35
1

You've had several answers to this on your Reddit post about this as well. In essence, you are trying to test for something that is not required. If the user enters 15 rather than 15.00, it's perfectly valid. You don't need to require the user to enter 2 decimal places. As a matter of fact, if you do that, you won't pass check50 as at least one of the test inputs is a large number with no decimal places.

2
  • I'm going by the videos etc that suggest that you x100 then cast to an int. If the change required is 1.57 and the entry made is 157 my math goes out the window. THAT is, in a nutshell what I'm trying to catch – fuego pazzo Oct 4 '14 at 0:37
  • I can understand what you are trying to avoid. But the spec does not say that you need to avoid that. If the user enters 157, then you should assume that they want 157 dollars worth of coins (15700 cents). – curiouskiwi Oct 4 '14 at 1:04
1

From the perspective of your program, you should consider GetFloat to be used only for retrieving data, not validating it.

Internally, GetFloat uses fgetc to capture characters from stdin. Here's where that happens in the source code for the CS50 Library:

// try to get a float from user
while (true)
{
    // get line of text, returning FLT_MAX on failure
    string line = GetString();
    if (line == NULL)
        return FLT_MAX;

You might be thinking, "Where's fgetc?" It's in GetString, here:

int c;

// iteratively get chars from standard input
while ((c = fgetc(stdin)) != '\n' && c != EOF)
{

Don't try to understand every part of this right now; when you reach problem set 6, you'll be using fgetc on your own and this library will start to make more sense. The important things to notice here are:

  1. GetString stores every character the user inputs in the variable c before checking if it belongs in the string (i.e., not EOF);
  2. GetFloat stores the entire string input by the user in the variable line before doing any sort of validation;
  3. After storing the string, GetFloat uses a conditional statement to perform one validation action (it also checks, in the following lines, to make sure the input is purely numeric; you don't need to worry about that code).

That's how you should think about validation – first you store the user's input whether it's valid or not, then you examine the data you stored to determine whether it meets your requirements. Before writing this as actual code, you should plan out the flow of control in your program and decide what types of invalid input you're likely to get, and will need to handle.

Whoever wrote GetFloat obviously expected that they might get NULL as input, so they wrote if (line == NULL) return FLT_MAX; to react to that particular type of invalid input by passing control back to the caller of the function, returning a special constant value to represent failure. (They could have done something else, but this is what they decided to do; you have that freedom as well, as long as you meet the problem set specifications!) A bit later, there's some more complicated code that responds to non-numeric input by prompting Retry? and not passing control back to the caller, so that the while loop repeats itself.

The reason that GetFloat treats data like 1234 as valid is because in mathematical terms, there's no difference between 1234 and 1234.0; they represent the same number. How do you know that the user made a mistake? Maybe they meant $1,234. The programmer who wrote GetFloat decided it's better to trust the user when they enter a whole number value, instead of forcing them to type .0 at the end. That makes sense because the user doesn't usually know the difference between int and float, nor do they care! In the problem set 1 specification, the prompt used is O hai! How much change is owed? – instead of writing a bunch of extra code to validate input you suspect might be a mistake, you could just change the prompt to specifically ask for a number in decimal dollars and/or give an example of the right input format.

But in greedy, you're not required to do this; in fact, that the specification says:

By nature of floating-point values, that user could also have inputted just .41. (Were they to input 41, though, they’d get many more coins!)

If the user inputs a whole number, they should get "many more coins" – in other words, you should treat it as valid input. If it's not what they wanted, too bad; PEBCAK! The only thing you need to validate for this problem is that the input is non-negative:

If the user fails to provide a non-negative value, your program should re-prompt the user for a valid amount again and again until the user complies.

If you need more hints about how to prompt the user again and again until you get the right value, without my actually telling you what code to use, GetFloat does exactly that. Try reading it and figuring out its control structure; it's only about 20 lines long. A good technique for understanding the control structure of a complicated function is to replace code that doesn't affect flow of control with placeholders like do_stuff_here() and just focus on things like loops, conditional logic and return statements.

2
  • wow, thank you so much. This is way over my head at present but I will definitely check this out – fuego pazzo Oct 4 '14 at 0:35
  • Aha I read through your comment again and it's very useful. It would appear that I'm trying to overcomplicate things. Presumably I either don't have correct the user input . I did already stipulate how I wanted the change, namely '0.00' So, is that enough or do I still have to ensure a valid entry? – fuego pazzo Oct 4 '14 at 0:44
0

You can use a while loop to check if the number is positive.

GetFloat will not re-prompt as 1234 is also a floating point number(1234.0).

1234 is not an invalid input as it denotes 1234 dollars and 0 cents. So, there wouldn't be any use checking such a condition.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .