DANI ROLST DANI ROLST -4 years ago 105
C Question

Reading until I manage to enter an integer

I'm pretty new in C, I used to work in Python, and I'm trying to see if something that I read is integer number. If not, to read until I manage to entry a number.

I did some research and I found out that the function

scanf
actually returns 1 if the read is done suitably, and 0 otherwise.
So, I have written this code, and I don't understand why this is an infinite loop, writing "Give an integer" on the console

#include <stdio.h>

int main() {
int a;
int b = 1;
do {
printf("Give an integer\n");
b = scanf("%d", &a);
} while (b == 0);
}

Answer Source

I don t understand why this is an infinite loop, writing "Give an intiger" on the console

The problem is that scanf() does not consume data that it cannot match against the specified format. It leaves such characters unread in the input stream. Therefore, if you try reading again from the same stream with the same format, without consuming at least one character by some other means, then you can be certain that the input will again not be matched. And again. And again.

To avoid your infinite loop, you need to consume at least one character of the non-matching input after each matching failure. There are many ways you could do that; here's a fairly simple one:

#include <stdio.h>

int main() {
    int a;

    do {
        printf("Give an intiger\n");
        if (scanf("%d", &a)) {
            // breaks from the loop on a successful match or an error
            break;
        }
        // consume the remainder of one line of input without storing it
        if (scanf("%*[^\n]") == EOF) {
            break;
        }
    } while (1);
}

That consumes the whole remainder of the line on which the non-matching input is encountered, which will yield less surprising interactive behavior for some inputs than many alternatives would.

If you've a penchant for writing terse code, or if you don't like to break out of the middle of a loop, then you might write the same thing like this:

#include <stdio.h>

int main() {
    int a;

    do {
        printf("Give an intiger\n");
    } while ((scanf("%d", &a) == 0) && (scanf("%*[^\n]") != EOF));
}

Because the && operator short circuits, the second scanf() call will be executed only if the first returns zero, and the loop will exit after the first iteration wherein either the first scanf() call returns nonzero or the second returns EOF (indicating an error).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download