The following code snippet has been taken from Teach Yourself C by Herbert Schildt page 234.
#include <stdio.h>
int main(void)
{
char ch;
do
{
ch = getchar(); //suppose asdf is input
putchar('.');
} while (ch != '\n');
return 0;
}
Which returns,
asdf
.....
Process returned 0 (0x0) execution time : 0.050 s
Press any key to continue.
After this snippet Herbert Schildt writes, "Instead of printing a period between each character, what you will see on the screen is all the letters you typed before pressing ENTER, followed by a string of periods."
I am stuck with this snippet for a while
. I tried some variations of the snippet to understand it better, which raised more questions than answering. This is actually running against my current understanding. Rather than printing out the above output, my current understanding suggests the following output:
asdf //input asdf
.
asd //input asd
.
\n //hit ENTER
.
Process returned 0 (0x0) execution time : 0.050 s
Press any key to continue.
With the above introduction, I have the following questions:
- How the above snippet is looping even?
- What am I wrong with my current intuition?
CodePudding user response:
From the C Standard:
C17 § 7.21.3p7:
the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device
From the ANSI C standard:
Description:
"putchar" outputs a character to the standard output "stdout" and returns the character that was written.
By default, all output streams (including "stdout" and "stderr") are normally buffered. This means that a number of characters are saved internally in a memory area called a buffer. When the buffer is full, the characters are then written out as a group. If a program requests input from terminal for which there is buffered output, the output is automatically "flushed" to the terminal, after which the input function begins reading input.
From this, you may infer that getchar()
isn't given anything until a \n
is seen.
CodePudding user response:
Schildt has a reputation of not really understanding the difference between the C language and the environment the program runs in (among other things) [1, 2, 3]. You might be better served by another book.
But as for your specific question, here's what will generally happen.
The user hits the asdf keys. The operating system could choose to send them to the program immediately, but it's common for it to store them in a buffer until either 1) the buffer gets full or 2) the user enters a newline. The book assumes the buffering happens in this manner. The shell will also frequently echo the characters you're typing, so after typing asdf, "asdf" appears on the screen.
So when you type Enter, the program receives all the input (in the stdin stream) at once. (From this point forward, the behavior is governed entirely by C.) But getchar() only fetches one character from stdin at a time, so each time through the loop, it reads one character, then prints '.'. Upon reading the newline (and printing the corresponding '.'), the loop exits (without printing a trailing newline, although the environment might choose to add one).