morgoe
morgoe

Reputation: 350

C: For loop acting REALLY strangely with scanf

So I've got the following code:

int q, x, y;
char l;
for (q = 0; q<10; q+=1) {
    printf("%d\n", q);
    if (3 == scanf("%c %d %d", &l, &x, &y)) {
        printf("%d\n", q);
    }
}

I would expect this to run "scanf" 10 times. Each time it will print 'q' before I enter anything, and once again after. So the expected output should be this (correct me if I'm wrong):

0
> a 1 1
0
1
> b 2 2
1
2
> c 3 3
2
...and so on.

But I actually get this.

0
> a 1 1
1
1
2
> a 2 2
3
3
4
> a 3 3
5
5
6
> a 4 4
7
7
8
> a 5 5
9
9

If I take out the scanf function, it counts from 0-9 as expected. What's happening with the scanf function to make the for loop act so weirdly? I've got some experience in Java/Python, but I'm totally new to C.

Editing the code based on your comments to this (apologies for weird formatting):

for (q = 0; q<10; q+=1) {
        printf("%d: ", q);
        if (3 == scanf("%c %d %d ", &c, &x, &y)) printf("%d\n", q);
        else { printf("WTF %d\n", q); }
    }

half solves the problem. It works for all of the iterations EXCEPT for the first one. As so:

0: a 0 0
WTF 0
1: b 1 1
1
2: c 2 2
2

What's going on there? There is other outputted code above that first line, from another part of the program. Could that be causing this?

Upvotes: 2

Views: 1275

Answers (4)

rama
rama

Reputation: 1

scanf function is returning different values instead of 3(three inputs). I don't know exact reason but I feel because of spaces in scanf("%c space %d",&c,&i); function it is returning different values.

Upvotes: 0

John Bode
John Bode

Reputation: 123458

Unlike %s, %d, %f, and most other conversion specifiers, the %c conversion specifier doesn't skip over any leading whitespace, so it's picking up the newline from the previous entry.

After you type a 1 1 <Enter>, the contents of the input stream are {'a', '1', '1', '\n'}. The first scanf consumes the a, 1, and 1, leaving the trailing \n in the input stream. scanf returns 3 and you print the value of q.

The second time through the loop, scanf picks up the leftover \n and assigns it to l, but since there's nothing else in the input stream it doesn't assign x or y, so it returns a value of 1 and your branch isn't taken. Then the loop starts over again.

The easiest way around this problem is to put a leading space in the format string before the %c conversion specifier:

if (3 == scanf(" %c %d %d", &l, &x, &y))
  printf("%d\n", q);

That leading space in the format will cause scanf to skip over any leading whitespace in the input stream, so you won't accidentally pick up the trailing newline from the previous entry. Of course, if you want to pick up any whitespace characters, you'll have to do something different.

Upvotes: 4

Hanya
Hanya

Reputation: 21

Why don't you try adding an else statement and printf to your vars to debug this? It seems that for every time (3 == ..) is true, there is another time that it is false. scanf might be running twice for the newline character when you hit enter...

Upvotes: 2

strkol
strkol

Reputation: 2029

you have unconsumed "\n", getchar() will consume it:

if (3 == scanf("%c %d %d", &l, &x, &y)) {
    getchar();
    printf("%d\n", q);
}

Upvotes: 4

Related Questions