user3134186
user3134186

Reputation: 19

Why getchar() behaves differently?

I found getchar() is behaving differently in some situations.
In the following code, it devours the newline character in the input.

#include <stdio.h>

// copy input to output; 1st version
int main()
{
    int c;

    while((c = getchar()) != EOF) 
    {
        putchar(c);
    }
}

The input and output in the terminal looks like this.

j
j
b
b
asdf
asdf
ashdfn
ashdfn

It exactly duplicates the input and ignores the newline character in the input due to return key I pressed after each input.

However, if there is a printf() statement inside the loop, it no longer ignores the newline character.

#include <stdio.h>

// copy input to output; 1st version
int main()
{
    int c;

    while((c = getchar()) != EOF)
    {
        putchar(c);
        printf("\n");
    }
}

The input and output in the terminal looks like this.

j
j


b
b


asdf
a
s
d
f


ashdfn
a
s
h
d
f
n

It echoes the newline character, which was used to be ignored in the previous situation.

Could you tell me why there is a difference and how does it behave exactly?

Upvotes: 1

Views: 583

Answers (5)

haccks
haccks

Reputation: 105992

getchar reads a character at a time. When you input 123 and press Enter key then this input goes to the C standard buffer with one more character \n (generated on pressing Enter key). Now from there getchar reads a character at a time and rest of the characters in input stream left behind for the next call of getchar.
Now, to answer your question I am going to explain it with a simple program;

#include <stdio.h>

int main(void)
{
     int c, b;

     c = getchar();
     putchar(c);

     b = getchar();
     putchar(b);

     b = getchar();
     putchar(b);
 }  

Giving the input 123, the input stream of the buffer would be

123\n

Having four chars; '1', '2', '3' and '\n'.
First getchar reads 1 and then putchar output this character. Now the buffer have 23\n. Next call of getchar reads 2 and next to it will read 3. Finally \n is left behind for the next call of getchar. Hence the output will be

123

Now inputting the character one by one as in your first example. On passing j you are passing j\n to the buffer. First call of getchar will read j and is putchar output this on screen. Next call will read \n and putchar print this out on the screen but the effect is not seen to you until the read of next character. On third call of getchar, b is read but this time it goes to the next line on the output screen. This is because of the \n character read previously by getchar. Finally \n is left behind in the buffer for next call of getchar.

Now coming to your first example

#include <stdio.h>

// copy input to output; 1st version
int main()
{
    int c;

    while((c = getchar()) != EOF) 
    {
        putchar(c);
    }
} 

This will work similarly as stated above.

Now coming to your second example

#include <stdio.h>

// copy input to output; 1st version
int main()
{
    int c;

    while((c = getchar()) != EOF) 
    {
        putchar(c);
        printf("\n");
    }
} 

This is printing two newlines after each of character but supposed to print a single character, right?

It is printing what it should! This is because it is printing a newline not only for characters j, b...etc but also for newline character \n. Take simple input j\n, b\n.
On first call of getchar, j is read and printed with a newline by printf then on next call \n is printed along with a newline and the output looks like

j
    //The newline printed by printf along with j    
    //The newline printed by printf along with \n 
b   

Upvotes: 2

gaurav5430
gaurav5430

Reputation: 13882

in my opinion what is happening is, when you enter a character at the terminal, suppose 'a' and then press Enter, actually two characters are getting buffered in the input stream

'a' and '\n'

so the loop runs twice to putchar these two characters, that is why your next input starts at new line

(you may check that by using:

if(c!='\n') putchar(c);

this will cause the '\n' not to be printed and you would input on the same line)

when you add printf("\n"), it will also be printed twice because the loop will still run two times as there are two characters in the input stream.

so you will get

a
(newline from printf)

in the first iteration of the loop

(newline from input buffer)
(newline from printf)

in the second iteration

Upvotes: 0

udit bansal
udit bansal

Reputation: 106

Check http://ideone.com/H2kqBq

#include <stdio.h>
int main()
{
int c;

while((c = getchar()) != EOF)
{
    putchar(c);
    printf("\n");
}
}

The output is not as you have specified here.

The behaviour of getchar() and putchar() is consistent

Upvotes: 0

user1814023
user1814023

Reputation:

It is not echoing the newline. getchar() is buffered input. Also, getchar() is of echoing type. The control will wait until you press Enter key from the keyboard.

If you do

abcdeEnter

since getchar() is of echoing type, it reads single char from the buffer until it encounters newline and the same char is echoed. The putchar() prints the received char on the terminal. The newline which is being output is entered by you when you press Enter.

The same thing happens in the second case, but one extra line is added because of printf.

Upvotes: 0

Rohan
Rohan

Reputation: 53316

In first case, it reads one character - getchar() and prints it - putchar(), so there is not newline or '\n' after each character. The newline is the one you entered with enter key press.

While in 2nd case, you have printf("\n") which prints new line after every character is printed - through putchar().

Upvotes: 2

Related Questions