I'm confused how scanf can work together with getchar. I was under the assumption that scanf can get the user input and then when the user presses enter it assigns the input respectively. While, getchar works by getting each character and assigning it to the variable getchar was assigned to. Looking at this code:
#include <stdio.h>
int main (){
int num, i;
char ch;
printf("Enter an expression: ");
scanf("%d", &i);
while ((ch = getchar()) != '\n'){
if (ch == ' '){
scanf("%d", &num);
i = num;
break;
}
}
printf("%d", i);
}
Shouldn't I get to input 3 times? The first scanf and then the getchar and then the last scanf, or am I missing something key here? I'm new to C and I hope you don't mind this (probably stupid) question of mine :)
CodePudding user response:
scanf
is not involved in transferring data when the user pressed enter.
C programs have streams of data. (Even though they are handled with a FILE *
type, they are streams, not files.) scanf
reads from the standard input stream. Commonly, the standard input stream is connected to a terminal device (in the old days, a physical terminal device, these days, more likely a software terminal window). The terminal device has protocols about when it sends data the user has typed to the stream. Again most commonly, when the user presses enter, the data they have typed is sent to the stream. Also, on Unix systems, pressing control-D sends the typed data to the stream.
To do its work, scanf
asks the stream for a character. Then it analyzes how the character matches the conversion it is working on. For example, when scanf
is working on a %d
conversion, it expects there may be some white-space characters at the start (which it skips), then maybe a “ ” or “-”, then some digits. Any other character stops the conversion. So, when scanf
starts on a %d
conversion, it gets a character. If no character is available, perhaps because the user has typed something but not yet pressed enter, then scanf
just sits there waiting until a character arrives. When the user presses enter, scanf
gets the first character.
Note that scanf
was not involved in waiting for enter to be pressed. That is a function of the terminal. At this point, scanf
only has the first character and does not know whether enter was pressed.
After scanf
reads the digits, it reads the next character. When that character does not match the %d
pattern, it puts the character back into the stream. So, if the user types “123 456”, scanf
processes the “123”, gets the “ ”, rejects the “ ”, and pushes the “ ” back into the stream.
Then getchar
gets the “ ” and returns it.
Then the later scanf
reads the “456”. It also sees the new-line character the terminal put into the stream for the enter key, and it rejects it and pushes it back into the stream.