如何阻止输入字符卡在缓冲区? C

时间:2016-11-16 14:54:09

标签: c stdin stdio getchar

因此,在下面的代码中,我从用户那里读取一个选项,然后决定是否执行给定的操作:

printf("Do you want to execute %s: ", exe);

char input = getchar();

if (input == 'y') {
    return execute(exe);
} return 0;

我遇到的问题是在char input = getchar()行之后,一个字符(我假设输入密钥或换行符)卡在stdin中,以及将来调用因此,fgets()函数中的stdin(从execute()读取)会消耗这个卡住的字符并且不会提示用户输入所需的内容。

现在我可以定义以下功能来“吃”'如果在调用execute()之前调用了我的任何迷路字符......

void iflush() {
    int c;

    while ((c = getchar()) != EOF && c != '\n') {
        continue;
    }
}

......这解决了这个问题。但是我想知道为什么这首先发生了?有没有更合适的'从char获取stdin而不会导致这个流浪角色然后弄乱我的其他方法的方法?我对C很陌生,我很想确定我是否有良好的学习习惯。

我必须添加一个辅助方法,即使很简单,以防止我的程序中的错误只是记录一些用户输入,这似乎很奇怪。我已经尝试过使用fgetc()同样的问题。

1 个答案:

答案 0 :(得分:4)

  

我想知道为什么会发生这种情况?

这是因为当你可以使用%c(或fgetc())的字符时,它不会忽略输入流中的空格。 某些格式说明符(例如%d)会忽略输入流中剩余的任何空格。所以,这不是问题。但是%c并没有忽略它。 因此,您通常使用那些“吃”功能。

如果您正在扫描空格字符(例如 space ,换行符等),您是如何使用scanf()扫描它的? 显然,有不同的更好的方式,例如使用fgets()

  

我对C很陌生,我很想确定我正在学习好习惯。

我的建议是完全避免scanf()。而是使用fgets()读取一行,然后使用sscanf()解析该行。请阅读:Why does everyone say not to use scanf? What should I use instead?

要注意fgets()的一件事是,如果输入缓冲区有足够的空间,那么它也会读取换行符, 您希望在大多数用户输入中避免使用它。因此,您需要检查最后一个字符是否为换行符,然后将其删除。

您可以使用strcspn()功能实现它,例如:

char line[256];
if (fgets(line, sizeof line, stdin) == NULL) {
    /* handle failure */
}
line[strcspn(line, "\n")] = 0; /* remove the newline char if present */

如果你主要只想读一个字符,那么数组3个字符就足够了。仍然使用更大的缓冲区并没有伤害:

char line[256];
char ch;
if (fgets(line, sizeof line, stdin) == NULL) {
    /* handle failure */
}
if (sscanf(line, "%c", &ch) != 1) {
    /* handle failure */        
}
/* Now you can use 'ch' to check if it's 'y' */