2
votes

I have some trouble working with scanf in a while loop. I wanted to make a program that would ask the user to write three integers and save them in an array of three positions. If the user writes something which is not an integer, the program should continue asking for an integer until (s)he enters it. But it didn't work properly.

So I tried to simplify the problem with this code:

#include <stdio.h>

int main()
{
    int num1=1;
    int num2=2;
    int num3=3;

    printf ("write a number\n");
    scanf("%i", &(num1));
    printf("%i\n",num1);

    printf ("write a number2\n");
    scanf("%i", &(num2));
    printf("%i\n",num2);

    printf ("write a number3\n");
    scanf("%i", &(num3));
    printf("%i\n",num3);
}

If the inputs are 3 integers, there's no problem. But if you write a character, for example a, for the first integer, the other 2 values are not scanned and it simply writes: a 2 3 The last two values are the initialization values.

Can anyone tell me what I have to do?

2
You have to use fgets(). - user529758
Thanks for your help. But could you please explain me what is happening? - Trouble-lling
@Trouble-lling Actually, I don't exactly know. I don't use scanf(), exactly for its pieces of misbehavior like this one. - user529758

2 Answers

3
votes

The scanf function does not have to read after it encounters the first invalid character in the input.

The %i specifier allows a as a hexadecimal, but it MUST be preceded by 0x.

If a was the first character in the input, and it was supposed to match to %i, then scanf wouldn't have to read anything afterwards - it can stop at the first invalid character..

References: http://www.gidnetwork.com/b-64.html

1
votes

For each conversion specifier scanf tries to locate the appropriate data item. scanf reads the item, stopping when it encounters a character that can't possibly belongs to the item. If any item is not read successfully then scanf returns immediately without looking at the rest of the format string.
When you enter a 5 10, scanf finds a for the specifier %i. It immediately returns and stops reading other inputs 5 and 10.