3

Please i'm having an issue with my program. Whenever i try to input a float it's getting into an infinity loop. I know that the input is stored as an integer. How can prevent the user from entering a float (how to filter the input).

Why is the program getting into an infinite loop when the input is a float.

This is an example:

#include <stdio.h>

main()
{
    int i = 0;
    while(i<10){
        system("cls>null");
        printf("%d^2 = %d\n", i, i*i);

        printf("Index: ");
        scanf("%d", &i);
    }
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
rullof
  • 7,124
  • 6
  • 27
  • 36

3 Answers3

2

Better use fgets() to read a complete line from stdin, and strtol() to parse it into an number, for example:

char buffer[256];
char *endp;
int i;
while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
    // buffer now contains one line (including the terminating newline)
    i = (int)strtol(buffer, &endp, 10);
    // endp points to the first character after the parsed number:
    if (endp > buffer && (*endp == 0 || isspace(*endp))) {
        printf("%d^2 = %d\n", i, i*i);
    } else {
        printf("invalid input\n");
    }
}
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
2

When you call scanf to read a number, but the input contains something incompatible with the input format specifier, scanf does not consume such incorrect input, leaving it in the buffer. Your program does not clear the buffer on input mismatch, entering an infinite loop: scanf tries to read an int again, sees that it's not there, and exits without modifying i. Your loop sees that i is less than 10, and calls the scanf again.

To fix this, check that scanf returned one input. Use the input when it is correct, or call scanf again with the %*[^\n]\n specifier, which means "read to the end of the string, and discard the input":

if (scanf("%d", &i) != 1) {
    scanf("%*[^\n]\n");
}

Note the asterisk - it means that the consumed input needs to be discarded, rather than being written into a variable.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • How does it get the input when it read it to the end? is it works like the casting? – rullof Dec 15 '13 at 11:50
  • The `[^\n]` format means "string consisting of any characters except newline, repeated any number of times". Asterisk tells `scanf` to discard that string. `\n` at the end removes the `\n` from the buffer. So `scanf("%*[^\n]\n");` call removes the current line from the input buffer, without even looking at its content. By the way, inside that `if (scanf("%d", &i) != 1)` is a good place to add a `printf` telling the user that the input is not valid, and that he should please enter another integer value. – Sergey Kalinichenko Dec 15 '13 at 11:55
0
#include <math.h>
#include <stdio.h>

int main (void)
{
    int i = 0;
    float j = 0;
    while(i<10)
    {
        system("cls");
        printf("%d^2 = %d\n", i, i*i);

        printf("Index: ");
        if (scanf("%f", &j) <= 0 && j-fabs(j) != 0)
        {
             printf ("The input is not an interger");
        }
    }
}
Kevin Dong
  • 5,001
  • 9
  • 29
  • 62