tags:

views:

292

answers:

3

I'm trying to match lines with a format like "point %d %d". So I only need to two those two integers, then the "point" is hard-coded in the format string. As I understand reading Linux man pages of scanf, this should work correctly.

The next code, the way I want to use, the first call to scanf works, but the next calls scanf return with an error code and never take more numbers from the stdin (scanf doesn't block waiting for more input from stdin):

for (;;)
{
 scanf("point %d %d", &x, &y);
 printf("=> point %d %d\n", x, y);
}

In this way, everything work as expected:

    int x, y;
    char s[10];

    for (;;)
    {
       scanf("%s %d %d", s, &x, &y);
     printf("=> point %d %d\n", x, y);
    }

Any suggestion about what could I am misunderstanding?

Thanks.

+1  A: 

My guess is that you are not giving it proper input. For example this input will not work:

4 5

This should work:

point 4 5

You didn't mention the error code, but it is probably saying that you didn't follow the format correctly (i.e. put in point before the numbers).

Zifre
Yes, scanf needs to match "point" before it can match two numbers. In the second example, %s matches the empty string.
Andrew Keeton
Also, unruly newlines too.
Andrew Keeton
Well, obviously I'm putting in the stdin lines like "point 4 5" because that's the format I'm working with. So, it's not a problem with the format, also I don't want to detect error in the input by now.So in the first line from the stdin (i.e.: "point 4 5") work ok, get the 4 and the 5. The return code is 2 (two elements taken).In the second line (lines with similar correct format) and following, none is taken, scanf doesn't even block to wait more input from the stdin and the return code is always 0 (none elements take, so that notice the error).
Ricardo
+3  A: 

There's still unconsumed data such as end-of-line characters in stdin that make the upcoming scans to stop with a non-match. In the second version this end-of-line data gets consumed by the %s.

I suggest you fgets to a buffer first and then sscanf it. And do check your return values.

laalto
OK, what you say solve my problems, thank you. Now I call scanf(" point %d %d", The *blank* before "point" takes out the end-of-line characters from the stdin and now it works.
Ricardo
A: 

As a good programming practice you should flush the standard input before taking inputs from user.

Vaibhav
And how do you do that, portably? For example, fflush is guaranteed to work on output streams only, although in some implementations fflushing an input stream discards whatever input there is.
laalto
Ricardo
I agree that in some compilers this is undefined behavior. Basicly it's "supposed to" clear the input stream of all pending input, thus making it clear for you to begin reading again without having junk input.This will work in MSVC++, because according to the msdn, their implementation of fflush will clear any stream passed to it.However, this will not work on all compilers, because it is not a defined behaviour. This means that the ANSI standard commitee haven't specified what should happen when you flush an input stream.
Vaibhav