0

There is a similar question here(on which this question is based)

Check if input is integer type in C and related answer https://stackoverflow.com/a/4072483/3395716

The difference is that in that answer only one integer is checked, but I want to check multiple numbers and then quit.

I modified the program like this,

//variable declaration
flag=0;
    if(scanf("%d%c", &A, &term) != 2 || term != '\n')
    {
        flag=1;
    }
    if(scanf("%d%c",&B, &term) != 2 || term != '\n')
    {
        flag=1;
    }
    if(scanf("%d%c",&C,&term) != 2 || term != '\n')
    {
       flag=1;
    }
    if(flag==1)
    {
        printf("failure\n");
        return 0;
    }

The problem is, the program doesn't wait for all numbers to be inputed, rather if, say first input is invalid, it will just print failure.

What should I do?

EDIT: example input and output

5
6
7
output:nothing

expected

input:
5
f
7
output:failure

what happens

5
f
output:failure
Community
  • 1
  • 1
Registered User
  • 2,239
  • 3
  • 32
  • 58

3 Answers3

3

The problem is that if there is invalid input, the scanf function will not read the input, it will be left in the input buffer for the next input function, which in your case will fail with the same input.

I recommend you use e.g. fgets to read the whole line, and then use e.g. sscanf (or strtol) to convert the string to a number.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Another alternative is to discard the remainder of the line *after* the `scanf` call, using something like: `scanf("%*[^\n]"); getchar();` rather than tacking `%c` onto the end of the format string... Either way, the result is the same: user input will be discarded in this case, which is probably undesirable. – autistic Aug 08 '15 at 06:58
  • I used sscanf.How would I check if input is invalid? – Registered User Aug 08 '15 at 07:08
  • @RegisteredUser Just like with the normal [`scanf`](http://en.cppreference.com/w/c/io/fscanf) function, by checking the return value. – Some programmer dude Aug 08 '15 at 07:17
1

Here's the problem: if the user types A and presses enter, then the first scanf fails because it sees the A, but the A remains in the input stream. So the second and third scanf will also see the A and fail immediately.

In general, if you need to enforce a line-oriented protocol, you should use fgets to read a line, and use sscanf and/or the strto* family of functions to do the conversions.

user3386109
  • 34,287
  • 7
  • 49
  • 68
  • I used sscanf to do the conversion, but how would I check if input is invalid – Registered User Aug 08 '15 at 07:17
  • @RegisteredUser Same as you did with `scanf`, you would `if(sscanf(buffer,"%d%c", &A, &term) != 2 || term != '\n')`. Normally, the fact that `fgets` puts the `'\n'` at the end of the buffer is a nuisance, but in your case, it's exactly what you want. – user3386109 Aug 08 '15 at 07:28
0

scanf("%d ... does read the invalid character 'f', but seeing that it is not an expected part of a int (because of the "%d"), ungets the character, putting it back into stdin for subsequent reading/scanning.

So until something consumes the 'f', additional calls with scanf("%d%c", ... will not change the status of things.

Better to use fgets() (C standard) or getline() (common, but not standard) to read user input.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256