8

我很难理解getchar()。在以下程序getchar中按预期工作:

#include <stdio.h>


int main()
{
    printf("Type Enter to continue...");
    getchar();
    return 0; 
} 

但是,在以下程序中,getchar不会产生延迟并且程序结束:

#include <stdio.h>

int main()
{
    char command[100];
    scanf("%s", command );
    printf("Type Enter to continue...");
    getchar();
    return 0; 
} 

我有以下奇怪的解决方法,它有效,但我不明白为什么:

#include <stdio.h>

int main()
{
    char command[100];
    int i;
    scanf("%s", command );
    printf("Type Enter to continue...");
    while ( getchar() != '\n') {
      i=0; 
    }
    getchar();
    return 0;    
}

所以我的问题是:
1. 在scanf做什么?为什么这样scanf做?
2. 为什么我的工作围绕着工作?
3.模拟以下Python代码的好方法是什么:

raw_input("Type Enter to continue")
4

5 回答 5

12

输入仅在您输入换行符后发送到程序,但是

scanf("%s", command );

将换行符留在输入缓冲区中,因为%s(1)格式在某个非空白字符之后遇到第一个空白字符时停止,getchar()然后立即返回该换行符并且不需要等待进一步的输入。

您的解决方法有效,因为它在再次调用之前清除了输入缓冲区中的换行符getchar()

要模拟该行为,请在打印消息之前清除输入缓冲区,

scanf("%s", command);
int c;
do {
    c = getchar();
}while(c != '\n' && c != EOF);
if (c == EOF) {
    // input stream ended, do something about it, exit perhaps
} else {
    printf("Type Enter to continue\n");
    getchar();
}

(1)请注意,使用%sinscanf非常不安全,您应该将输入限制为缓冲区可以容纳的字段宽度,scanf("%99s", command)最多会将 99 ( sizeof(command) - 1)) 个字符读入command,为 0 终止符留出空间。

于 2012-09-29T15:13:17.273 回答
3

空白是 5y3 %s 格式说明符的分隔符,换行符被视为空白,因此它保持缓冲。控制台输入通常是面向行的,因此对 getchar() 的后续调用将立即返回,因为“行”仍处于缓冲状态。

scanf("%s", command );
while( getchar() != '\n' ){ /* flush to end of input line */ }

同样,如果您使用 getchar() 或 %c 获取单个字符,您通常需要刷新该行,但在这种情况下,输入的字符本身可能是换行符,因此您需要稍微不同的解决方案:

scanf("%c", ch );
while( ch != '\n' && getchar() != '\n' ){ /* flush to end of input line */ }

对于 getchar() 类似:

ch = getchar();
while( ch != '\n' && getchar() != '\n' ){ /* flush to end of input line */ }

当然,明智的做法是将这些解决方案包装到独立的专用输入函数中,您可以重复使用这些函数,也可以将其用作放置通用输入验证和错误检查代码的地方(如 Daniel Fischer 的答案中明智地检查 EOF -您通常希望避免在任何地方重复这些检查和错误处理)。

于 2012-09-29T15:36:15.707 回答
2

我宁愿先使用fgets然后使用sscanf来解析输入。我一直在做这样的事情很长一段时间,并且这种行为比使用 plain 更可预测scanf

于 2012-09-29T19:09:45.083 回答
-2

好吧,我有一些更简单的事情:添加另一个getchar()......问题解决了!

于 2014-09-20T16:51:24.957 回答
-4

接受命令输入后刷新标准输入。

fflush(stdin);

但是刷新输入流会导致未定义的行为(尽管 Microsoft 的 C 库将行为定义为扩展)。

于 2012-09-29T15:21:55.610 回答