What's the better way to read a char?
i write a little code to simply read a char from the keyboard but the program fails, why? How must i read a char?
int main(int argc, char** argv)
{
char op;
do
{
printf("¿Sigues?");
scanf("%c",&开发者_如何学运维op);
}while(op=='s' || op=='S');
return 0;
}
Your problem is that the %c
conversion specifier doesn't cause scanf()
to skip leading whitespace. You need to handle the newline character that's still in the stream after reading your input.
The input stream is empty when scanf()
is called the first time through the loop, so it waits for you to type something. You type s
and hit the Enter key, so the input stream contains the characters s
and \n
(newline). scanf()
removes the s
from the input stream and assigns it to op
. When scanf()
is called the second time, the input stream is not empty; it still has the \n
character in it, so scanf()
reads it and assigns it to op
, which causes the loop condition to fail, so your loop exits.
There are several ways to get around this problem. I'm going to recommend reading strings as opposed to individual characters using fgets()
, as follows:
char op[3] = {0}; // input character + newline character + 0 terminator
do
{
printf("¿Sigues?");
if (fgets(op, sizeof op, stdin))
{
/**
* Check for a newline character in the input. If it's not there
* then the user typed in too many characters. In order to keep
* the input stream from getting clogged up with bad input, read
* until we find a newline character.
*/
char tmp[3];
char *newline = strchr(op, '\n');
while (!newline && fgets(tmp, sizeof tmp, stdin))
{
newline = strchr(tmp, '\n');
}
}
else
{
printf("Error while reading input\n");
op[0] = 0;
}
} while (tolower(op[0]) == 's');
op = getc(stdin);
scanf flushes only after reading a newline. it cant be done in platform independent way
You're seeing the line "Sigues" twice because there's a \n
still in the input stream. If you type in a character and hit enter there are now two characters in your input stream. Your scanf
formatter only specifies one char, so scanf
reads in one char and then advances. However, the next character in the stream is a \n
, hence the exit from the loop on the second go.
NB. @eduffy's technique of getc(stdin)
will do the exact same thing, there's still a \n
in stdin. You need to advance past that \n
somehow.
How about reading in your char, and then chomping the rest of the stream up to the \n
char? I tried this and it works for me:
char op;
do
{
printf("¿Sigues?");
scanf("%c",&op);
while(getchar() != '\n') continue;
}while(op=='s'|| op=='S');
精彩评论