Validating float variable in C

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • beacon
    Contributor
    • Aug 2007
    • 579

    Validating float variable in C

    Hi everybody,

    I've just started programming in C and I've run into a problem. The compiler I'm using was distributed by the school and is a piece of work. Something is obviously wrong with it...maybe it's not ANSI compliant or something.

    Anyway, I'm trying to figure out if there's a way to read in user input and test to see if it's valid. I'm working with float variables because we're returning currency amounts, but understand that I may have to read the user's input in as a string and then go from there. Problem is, I'm not really sure where to go from there because I don't know if it's possible.

    When the value is read in, I need to return a message to the user if the value is incorrect and prompt them to re-enter until they get it right.

    Here's my attempt (using pseudocode):
    Code:
    float amount = 0.0;
    
    do{
    printf("Please enter an amount: ");
    scanf("%f", amount);
    
    if (amount != non-numeric character)
    return 1;
    else
    printf("Invalid amount.\n\n");
    return 2;
    }while(2);
    Thanks,
    beacon
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    If you scanf with %f you will automatically not get any invalid characters. You can not test amount against invalid characters because amount has type float, it is not character based.

    So first a couple of best practice guidelines:

    With modern computers which have large amounts of memory there is little reason to use float rather than double. Therefore you should not use float in favour of double unless you have a valid and defensible reason to do so.

    scanf is a very poor function (especially if used to enter a string using %s) and is best avoided. The function of choice for user input would be fgets which protects against buffer overrun errors.

    If working with a fixed point (fixed number of decimal places) then it is often easier and more accurate if using comparisons to use integer types rather than floating point types. For instance in the case of currency assuming you are using $ rather than hold $ as a float hold cents as an integer.


    If you really want to using floating point types then for your program I would use fgets to read in the string and then strtod to convert it to a double.

    Otherwise I would use fgets to read the string and strtol to convert the various parts of it to cents.

    Comment

    • beacon
      Contributor
      • Aug 2007
      • 579

      #3
      Hi Banfa,

      Ok, so let me try this again. I'm not sure I completely understand what to do, but I'm going to take my best shot. Btw, it doesn't really matter if I use float or double.

      Code:
      char strAmount[10];
      
      do{
      printf("Please enter an amount: "); 
      fgets(strAmount, 10, stdin);
      
      if((strAmount == 46) || (strAmount < 58 && strAmount > 47)
      return 1;
      else
      printf("Invalid amount.\n\n");
      return 2;
      }while(2);
      If I use strtol or strtod, will it return everything if the user enters 49.99? I'm not sure exactly how I would go about converting "the various parts of it to cents."

      Comment

      • Banfa
        Recognized Expert Expert
        • Feb 2006
        • 9067

        #4
        If it doesn't matter if you use float or double then use double.

        Between you fgets and your if you need to convert from a character string to a binary value (either float point or integer type).

        strtod would convert all of 49.99 were as when using strtol you would change to call it once to convert the 49, then skip the . and then call it again to convert the 99 then combine the 2 values into a total cents. strtol actually makes this relatively easy and you could easily write a function to take a string of the form nn.mm and produce the result nnmm in an integer (or an error).

        That may seem complex however the test amount == 46 will not (or is extremely unlikely) work for floating point types (float, double). This is because a floating point type holds an approximation to a value the chances of it holding 46 even if you entered 46.00 are small.

        This is the reason I suggest reading the value in in cents and store it in an integer. Integers do not suffer from the approximation of floating points so the test amount == 4600 (*100 because we are now working in cents) will work for a floating point.

        Comment

        • JosAH
          Recognized Expert MVP
          • Mar 2007
          • 11453

          #5
          Originally posted by beacon
          I'm working with float variables because we're returning currency amounts
          Ding! You fell for the trap: never, ever use floating point numbers for monetary values; they can't even represent the value of a dime exactly. The first article in this group shows a link about floating format pitfalls; read it.

          kind regards,

          Jos

          Comment

          Working...