2

May Someone help me understand why in case the first input was 'K' then scanf won't ask me to submit the second input?

int n=0;
scanf("%d",&n);
scanf("%d",&n);

It's like it got the input from somewhere else! in this case what would be the value of n?

John
  • 69
  • 3
  • 4
    Always check the return value when calling functions. `scanf` will stop as soon as it can't parse the input. The return value tells you how many items `scanf` successfully matched. Unmatched input is left in the stream and variables associated with unmatched specifiers are not changed. – kaylum Nov 25 '19 at 23:32
  • 1
    That's why `scanf()` returns a value that tells you if it succeeded or not. And this is also why using `scanf()` to read input is a really bad idea - if the input isn't what's expected, your input stream is left in an indeterminate state. – Andrew Henle Nov 25 '19 at 23:33
  • I suspect [one of *many* underlying duplicates](https://stackoverflow.com/questions/4016073/scanf-fails-why). – WhozCraig Nov 26 '19 at 00:00
  • 2
    *May Someone help me understand why...* Because `scanf` is a very, very poorly designed, nearly useless function. I encourage all C programmers either to not use it at all, or to use it for very simple stuff for the first few weeks, then graduate to something better. And during those first few weeks while you're using it, only give it perfect input; don't even try to figure out what it does (let alone try to make it behave more gracefully) when given mismatched input. – Steve Summit Nov 26 '19 at 00:31
  • @SteveSummit, Can you please express which functions better to use instead of `scanf()`. – EsmaeelE Nov 26 '19 at 00:39
  • @EsmaeelE For starters, see [this question](https://stackoverflow.com/questions/58403537/what-can-i-use-to-parse-input-instead-of-scanf). – Steve Summit Nov 26 '19 at 04:19

1 Answers1

0

If we check scanf() return value its shows 0

#include <stdio.h>

int main(int argc, char **argv)
{

    int n=0;
    int retvalue=0;

    retvalue = scanf("%d",&n);
    printf("first scanf() return: %d\n", retvalue);

    retvalue = scanf("%d", &n);
    printf("seconf scanf() return: %d\n", retvalue);

    return 0;
}

scanf() documents on opengroup website

these functions shall return the number of successfully matched and assigned input items; this number can be zero in the event of an early matching failure.

As you enter a character value, and scanf() function set to mach/accept "%d" (decimal number) it fails.

[Edit after comment]

If the first scanf() doesn't match the format specification, then the input isn't consumed and remains in the input buffer.

In other words, the character that doesn't match remains in input buffer and second scanf() use it as input similarly second one also fail.

Warning

fflush(stdin) solve this kind of misbehavior, but don't use because of fflush() on stdin cause Undefined behavior.

[Edit2]

In this case a getchar() call will Consume remaining buffer in stdin.

int n=0;
int retvalue=0;

retvalue = scanf("%d",&n);
printf("first scanf() return: %d\n", retvalue);

if(!retvalue)
    getchar();

retvalue = scanf("%d", &n);


printf("seconf scanf() return: %d\n", retvalue);

if(!retvalue)
    getchar();   
EsmaeelE
  • 1,681
  • 5
  • 15
  • 22
  • I think the OP understands why the first `scanf` fails. The underlying question is why did the *second* `scanf` *also* fail without prompt to the user. – WhozCraig Nov 25 '19 at 23:59
  • 2
    “fflush() on stdin cause Undefined behavior” contradicts “fflush(stdin) solve this kind of misbehavior”. A correct statement is that `fflush(stdin)` is defined by Microsofts “C” implementation (such as it is) to remove received but unprocessed characters from the input stream but is not defined by the C standard and hence cannot be used for portable behavior. In any case, advising people to use `fflush(stdin)` is a bad idea, since it is not portable. One can portably discard unwanted input by executing `getchar()` (and testing for EOF) after each failing `scanf` and then retrying the `scanf`. – Eric Postpischil Nov 26 '19 at 00:18
  • Thanks, @EricPostpischil Related comment: https://stackoverflow.com/questions/2979209/using-fflushstdin).#comment31066899_2979209 – EsmaeelE Nov 26 '19 at 00:33
  • @EricPostpischil, Is it correct that: Usually it is a mistake to want to discard input buffers.[fpurge](https://linux.die.net/man/3/fpurge). – EsmaeelE Nov 26 '19 at 00:41
  • 1
    I do not expect it is usually a mistake to want to discard input buffers. If one has decided the user has typed something unacceptable, it can make sense to discard everything they have currently typed, inform them of the problem, and then solicit new input. – Eric Postpischil Nov 26 '19 at 01:11
  • Note that a single `getchar()` is inadequate. If the user has typed something that is not acceptable as a number, they may have typed a bunch. One needs to either discard everything on the current line, at least, or discard unacceptable characters until the next sequence of characters is an acceptable number, or possibly discard some other set of characters. – Eric Postpischil Nov 26 '19 at 01:12
  • @EricPostpischil, what is you suggest to use in this case. It is true when user type many character my `getchar()` method failed to consume buffer. – EsmaeelE Nov 26 '19 at 01:19
  • 1
    @EsmaeelE Yes, usually it is a mistake to want to discard input. Usually this means you're using `scanf`, and it has gotten "stuck" on bad input. But, seriously: the right way to fix this is to *not use `scanf` in the first place*. `scanf` is a very poor function. It might be barely adequate for "toy" programs and perfect input, but trying to handle erroneous input well is one of many, many things that it basically can't do at all. (You can try, but you'll always get unsatisfactory results, and it's simply more trouble than it's worth.) – Steve Summit Nov 27 '19 at 14:26
  • @EsmaeelE See also [this answer](https://stackoverflow.com/questions/2979209/using-fflushstdin/58884121#58884121). – Steve Summit Nov 27 '19 at 14:28
  • @SteveSummit: In situations were users would be expected to be typing ahead of what is being requested, a non-blocking "flush all pending input" can be useful if something unexpected happens and a program will need the user to respond. Unfortunately, the authors of C89 refused to define any standard ways of doing things which were supportable by most but not all implementations, leaving the language with a console input abstraction which is not well suited for interactive applications. – supercat Dec 04 '19 at 23:30