2
int main (int argc, char *argv [])
{
     char a = 'v';

     for (int i = 0; a != 'x'; ) 
     {        
         printf("Enter 'a' : "); 
         scanf("%c",&a);
     }

     return 0;
}

I ran it and gave input k. When I hit enter after this , why my printf runs 2 times when loop runs second times?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
user10056563
  • 105
  • 4

3 Answers3

3

To understand this behaviour, we can simulate step-by-step the execution.

printf("Enter 'a' : "); 
scanf("%c",&a); // User type in example 'a' and presses enter.

scanf "bufferize" a\n and places in a the value 'a'

The loop condition isn't satisfied, since 'a' == 'x' is false

printf("Enter 'a' : ");
scanf("%c",&a); // The buffer still contains `'\n'`

Since the buffer still contains unconsumed data, the next character ('\n') is placed in a and the loop continues.

The loop condition isn't satisfied, since '\n' == 'x' is false

printf("Enter 'a' : ");
scanf("%c",&a); // The buffer is empty now.

This gives you the illusion that the loop displays twice the printf, but in fact, the scanf kept reading the buffer without the need of user input.

If you enter more characters, in example qwerty, "Enter 'a' : " will be displayed 7 times, because "qwerty" contains 6 characters + '\n'


Note that using while (a != 'x') would suit better your needs than for (int i = 0; a != 'x'; )

Cid
  • 14,968
  • 4
  • 30
  • 45
2

When you use scanf and %c, it reads any character -- including the newline character you get when you press the ENTER key.

So if you run the program and type

a <Return>

you take two trips through the loop: one to read the 'a' and one to read the '\n'. If you type

<Space> <Space> a <Return>

it makes four trips through the loop. And if you type

x <Return>

it only makes one trip through the loop, because it notices you typed the 'x', and exits.

Things will become a little more clear if you print out each character you receive:

for (int i = 0; a != 'x'; )
{
    printf("Enter 'a' : ");
    scanf("%c",&a);
    printf("you typed %d =  %c\n", a, a);
}

When you see it printing

 you typed 10 =

that's one of the newlines. (The value of '\n' is 10 in ASCII.)

I said that %c reads any character -- but that's somewhat unusual. Most of scanf's other format specifiers -- %d, %f, %s, etc. -- skip over "whitespace" -- that is, spaces, tabs, newlines, and a few others. But %c does not skip over those, because its job is to read exactly one character, and someone thought you might want to use it to read whitespace characters, too.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
2

For starters this loop

for (int i = 0; a != 'x'; ) 

does not make sense at least because the variable i is not used within the loop.

Also this prompt

printf("Enter 'a' : ");

only confuses users. You are asking the user to enter the character 'a' while the loop stops when the character 'x' is entered.

This call of scanf

scanf("%c",&a);

reads all characters including white-space characters. It is the reason why the loop iterates one more. You have to write

scanf( " %c", &c );
        ^^^

In this case white spaces will be skipped.

From the C Standard (7.21.6.2 The fscanf function)

5 A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read

The program can look the following way

#include <stdio.h>

int main(void) 
{
    char c;

    do
    {
        printf( "Enter a character ('x' - exit): " );
    } while ( scanf( " %c", &c ) == 1 && c != 'x' );

    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335