2

I created a function to validate the input of real numbers . It is working well , but as the atof() function returns 0 upon failure, it is not possible to enter 0 as an input value. Anyone can give help to solve this?

float validate_float()
{
    float num;
    char str[8];
    do
    {
        printf("enter a float number:");
        fflush(stdin);
        gets(str);
        num=atof(str);
    }
    while(num==0);
    return num;
}
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
nosperov
  • 31
  • 1
  • 4
  • 1
    So your question is what should you do to circumvent this limitation of `atof`? – Pascal Cuoq May 27 '15 at 11:49
  • I would suggest putting the `while (num == 0);` on the same line as the closing brace `}` as what you have here confuses into thinking you have a stray `while` running an infinite loop – Eregrith May 27 '15 at 11:55
  • yes :). I have a variable that should only accept float values between -10 and 15, inclusive the 0. But I wanted to validate the data input, so that the user enter a letter the program not crashes. – nosperov May 27 '15 at 12:08
  • Thank you : )! I found this function, and works fine to :). int isfloat( char *str ) { double num; return sscanf(str, "%f", &num); } – nosperov May 27 '15 at 13:46

3 Answers3

5

Yes, that's a limitation for atof().

You can make use of strtof()/strtod() instead.

Syantax:

double strtod(const char *nptr, char **endptr);
float strtof(const char *nptr, char **endptr);

Note: To differenciate between an actual input 0 and a no conversion 0, you need to check the endptr.


Now that said, as also mentioned by others,

  • Do not use fflush(stdin). It invokes undefined behaviour.
  • Never use gets(), it suffers from possible buffer overflow. Use fgets() instead.
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
1

This is a well-known limitation of atof as standardized. To circumvent this limitation, use strtod instead and pass a non-null pointer for the second argument.

From the man page on my system:

double strtod(const char *restrict nptr, char **restrict endptr);

If endptr is not NULL, a pointer to the character after the last character used in the conversion is stored in the location referenced by endptr.

If no conversion is performed, zero is returned and the value of nptr is stored in the location referenced by endptr.

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
0
  1. Do not fflush() stdin it's undefined behavior.

  2. It's simple, just use this

    int isfloat(const char *value)
     {
        char *endptr;
        float num; 
        num = strtof(str, &endptr);
        if (*endptr != '\0')
            return 0;
        return 1;
     }
    
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97