Home > Software design >  How to check if scanf input is a number? (user input has to be a float)
How to check if scanf input is a number? (user input has to be a float)

Time:11-08

I´d like to check if user input is a float/integer or a letter. For this purpose the use of scanf() is important. My problem is that a letter is saved as zero but I can´t exclude it.

I tried building solving it with if and as a condition I tried isalpha() and is digit().I tried a bunch of other things, but it´s not worth mentioning.

CodePudding user response:

... to check if user input is a float/integer or a letter ...

scanf() is a weak function to use when input is either convertable as a float, integer or character - yet OP reports scanf() is obliged. Requirement to use scanf() is misguided.

First read a line of user input into a string. Be sure to limit input width.

char line[100   1];
if (scanf(" 0[^\n]", line) == 1) {
  // Successfully read a line

Now process the string. Use strtof(), strtoll() to parse for float, integer. Test the endptr for conversion success.

 char *endptr;   //  Record end of conversion.

 errno = 0;
 long long ll = strtoll(line, &endptr, 10);
 if (endptr > line && errno == 0 && *endptr == 0) {
   // Successfully parsed a long int
   printf("long long: %ld\n", ll);
 } else {
   errno = 0;
   float f = strtof(line, &endptr);
   if (endptr > line && *endptr == 0) {
     // Successfully parsed a float
     printf("float: %.9g\n", f);
   } else {
     printf("otherwise <%s>\n", line);
   }
 }

Additional code useful to detect empty or long lines.

CodePudding user response:

If the actual requirement is something like this:

Read a series of numbers (integers or floating-point numbers) from the user. Stop reading when the user types something other than a number, such as a letter.

, then the solution, using scanf, is perfectly straightforward:

#include <stdio.h>

int main() 
{
    int maxnums = 10;
    double numbers[maxnums];
    int i;

    for(i = 0; i < maxnums; i  ) {
        printf("enter a number, or nondigit to quit: ");
    fflush(stdout);

        double x;
    if(scanf("%lf", &x) != 1)
            break;

        numbers[i] = x;
    }

    int nnum = i;

    printf("you typed %d number(s):\n", nnum);

    for(i = 0; i < nnum; i  )
        printf("%d: %f\n", i, numbers[i]);
}

The loop stops (using the break statement; I hope you've gotten to that in class by now) if scanf returns something other than 1, indicating that no number could be read. The loop also stops after the user enters 10 numbers, because that's how big the input array is.

It looks like the loop reads only floating-point numbers, and in a sense it does, but if the user types a pure integer, like 123, without a decimal point, that's still perfectly acceptable as a floating-point input, and it will be read as the floating-point value 123.000.

On the other hand, if there was a requirement to be able to tell whether the user actually entered a pure integer versus a floating-point number, or if there was a requirement to do something else with the pure integers other than storing them in the same array with the floating-point inputs, or if there was a requirement to know (to read and perhaps process) the specific non-numeric input the user typed to terminate the input loop, none of those additional requirements could be met with this simple code. In fact, in my opinion, meeting any of those additional requirements using scanf is effectively impossible, and some completely different approach, not involving scanf, would be required.

  • Related