C语言 C getchar vs scanf

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3640604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:22:05  来源:igfitidea点击:

C getchar vs scanf

cscanfgetchar

提问by startuprob

I am confused by a piece of code found in a function I am studying:

我对我正在研究的函数中的一段代码感到困惑:

char GetCommand( void )
{
    char command;

    do {
        printf( "Enter command (q=quit, n=new, l=list):  " );
        scanf( "%c", &command );
        Flush();
    }
    while ( (command != 'q') && (command != 'n')
           && (command != 'l') );

    printf( "\n----------\n" );
    return( command );
}

void Flush( void ) {
    while ( getchar() != '\n' )
        ;
}

What I don't quite understand here is the usage of the Flush()function. I mean, the book I am reading explains it by saying that it prevents the user from inputting more than a single character and then having that character read when they are prompted for input the 2nd time.

我在这里不太明白的是Flush()函数的用法。我的意思是,我正在阅读的这本书解释说,它可以防止用户输入多个字符,然后在提示他们第二次输入时读取该字符。

What I don't understand is how Flush()is preventing this from happening. It doesn't DO anything. All it is is a whilecommand. (While this is true......what?????) Doesn't make sense.

我不明白的是如何Flush()防止这种情况发生。它什么也不做。它只是一个while命令。(虽然这是真的……什么??????) 没道理。

采纳答案by msw

getchar()has the side effect of removing the next character from the input buffer. The loop in Flushreads and discards characters until - and including - the newline \nending the line.

getchar()具有从输入缓冲区中删除下一个字符的副作用。循环Flush读取并丢弃字符,直到 - 并包括 -\n结束该行的换行符。

Since the scanfis told to read one and only one character (%c) this has the effect of ignoring everything else on that input line.

由于scanf被告知只读取一个字符 ( %c),因此会忽略该输入行上的所有其他内容。

It would probably be more clear if the scanf was replace with

如果将 scanf 替换为

command = getchar();

but it's actually a generally bad example as it does not handle End Of File well.

但它实际上是一个通常不好的例子,因为它不能很好地处理文件结尾。

In general scanfis best forgotten; fgetsand sscanfwork much better as one is responsible for getting the input and the other for parsing it. scanf(and fscanf) try to do too many jobs at once.

一般scanf最好忘记;fgets并且sscanf工作得更好,因为一个负责获取输入,另一个负责解析它。scanf(和fscanf)尝试一次做太多的工作。

回答by Borealid

getcharreads one character from standard input. If you put it in a whileloop, it will continue to read one character at a time until the condition is false.

getchar从标准输入读取一个字符。如果将其放入while循环中,它将继续一次读取一个字符,直到条件为假为止。

What the Flushfunction is doing is reading until it encounters a newline (\n). This is the character produced when the user hits the enter key.

Flush函数所做的是读取直到遇到换行符 ( \n)。这是用户按下回车键时产生的字符。

So, the code you gave will read one character (I'm unclear on why it uses scanffor this instead of simply getchar, which would be faster), and then discards the rest of the input until the user hits enter.

因此,您提供的代码将读取一个字符(我不清楚为什么它scanf用于 this 而不是简单的getchar,这会更快),然后丢弃其余的输入,直到用户按回车键。

If you were to feed this program foobar, it would take the fand discard the oobarin the Flushfunction. Without calling flush, the fcould go to one scanf, and the second scanfwould get the first o.

如果您要提供此程序foobar,它将在函数中使用f并丢弃。不打电话,可以去一个,第二个会得到第一个。oobarFlushflushfscanfscanfo

回答by David Peterson Harvey

When you enter your character and press Enter, a newline character is generated by you pressing the Enter key and it remains in the buffer. This is problematic because it will wait around until the next time you require user input and it will be used for that input. Flush is used to flush the newline character from the input buffer so you don't have that problem. Flush actually uses the newline in the input buffer when it reads it and it is discarded, so it is no longer in the buffer.

当您输入字符并按 Enter 时,按 Enter 键会生成一个换行符,它会保留在缓冲区中。这是有问题的,因为它会一直等到下次您需要用户输入时才会使用它。Flush 用于从输入缓冲区中刷新换行符,因此您不会遇到该问题。Flush 在读取它时实际上使用了输入缓冲区中的换行符并被丢弃,因此它不再在缓冲区中。