问题
I am taking a training course on "C" and running into a problem. It's hard to explain so I'll post the code. This is training syntax, so don't ask me why it's done the way it is. When both of these segment blocks are run in a main(), the second block does not behave as if it exists alone in the main(). I have tried several IDE thinking it might be a bug.
/* First Segment Block */
int c;
printf("Type a letter: ");
c = getchar();
printf("You typed '%c'\n",c);
/* OR - outputs the same, to demonstrate putchar */
printf("You typed '");
putchar(c);
printf("'\n\n");
/* Second Segment Block */
int a,b,d;
printf("Type two letters: ");
a = getchar();
b = getchar();
d = getchar();
printf("You typed '");
putchar(a);
printf("' and '");
putchar(b);
printf("' and '");
putchar(d);
printf("'\n");
In the second segment block, I added a 3rd variable to test my theory. When you type the requested 2 letters, the first getchar() picks up a new line and the second getchar() picks up the first letter. The 3rd getchar() picks up the second letter. If you comment out the entire first segment block, then it behaves correctly, picking up the first letter by the first getchar() and the second letter by the second getchar(), displaying the output as expected.
Here is the output when both run together.
Type a letter: k
You typed (k)
You typed 'k'
Type two letters: lk
You typed '
' and 'l' and 'k'
RUN SUCCESSFUL (total time: 9s)
When they are run individually, the output is below.
First Segment Output.
Type a letter: k
You typed (k)
You typed 'k'
RUN SUCCESSFUL (total time: 5s)
Second Segment Output.
Type two letters: rf
You typed 'r' and 'f' and '
'
RUN SUCCESSFUL (total time: 5s)
The 3rd getchar() is a newline and that is expected.
Can anyone explain why when both segments are run in the same main(), the behavior is different from when run seperate?
Thank you in advance, Daniel N. (C language beginner)
回答1:
On the first prompt, you type something like aEnter, so your input stream contains the characters 'a', '\n'
. The first getchar
call reads the a
and leaves the newline in the input stream.
In response to the second prompt, you type bcEnter, so your input stream now contains '\n', 'b', 'c', '\n'
.
You can probably figure out what happens from here - the next getchar
call reads that newline character from the input stream.
There are a couple of ways to deal with this. One is to test your input, and try again if it's a newline:
do
{
a = getchar();
} while ( a == '\n' ); // or while( isspace( a )), if you want to reject
// any whitespace character.
Another is to not use getchar
; instead, use scanf
with the %c
conversion specifier and a blank space in the format string:
scanf( " %c", &c ); // you will need to change the types of your
... // variables from int to char for this.
scanf( " %c", &a );
scanf( " %c", &b );
scanf( " %c", &c );
The leading space in the format string tells scanf
to ignore any leading whitespace, so you won't pick up the newline character.
回答2:
Both 'space' and '\n (new line)' are characters as well. So, getchar() is getting every character you enter. For example, if you press 'a (enter) b', it will read a='a',b='\n',d='b'.
回答3:
This is how input streams are. when the first segment is running and to enter the first char, you press enter. It is basically taken as character itself in the input stream. so if you enter 'a' and press enter, its like 'a\n' in input stream. Now with getchar, you read one char from input stream to your variable which is 'a' here. On giving you 'a', input stream is left with '\n' still. next time you do getchar, you will get '\n' as char. even if you enter new chars, it will always be first in stream ie, '\nabc....'
'\n' it just to explain new line character.
回答4:
This happens because your terminal is line buffered, so it's waiting for you to press Enter before passing any of the characters you've typed to your program. When you do press Enter, your program will receive any characters that you've typed, including the newline character (\n
) produced by the Enter key.
The actual sequence of events looks like this:
- Your program prints the first prompt.
- Your program calls
getchar()
, which tries to read a character from the standard input stream. Since the stream is currently empty, it pauses your program until some input arrives. - You see the prompt and press a key (say,
X
). Since your terminal is line buffered, your program doesn't see it yet, and so remains paused. - You press Enter. Your terminal now send the characters you typed (
X
and\n
) to your program. getchar()
returns the first character available to your program on the standard input, i.e.X
.- Your code now prints the second prompt, and calls
getchar()
again.getchar()
sees that there's another character (\n
) still waiting on the standard input, and returns it immediately.
来源:https://stackoverflow.com/questions/41168213/cant-figure-out-why-getchar-is-picking-up-newline-for-first-occurence-in-c