C-我可以使用scanf暂停循环等待用户按Enter吗?

时间:2019-06-16 20:53:31

标签: c user-interface scanf

在循环中,我需要暂停并等待用户通过按Enter键要求继续。

可以在循环中使用scanf()函数来暂停并等待用户按Enter继续吗?我需要的就像是RPG中的一样,您需要按A才能看到其余的对话。

根据我的测试,此功能似乎是暂停的不佳选择。

如果是这种情况,是否还有其他方法可以在C中产生此行为?

3 个答案:

答案 0 :(得分:2)

getchar()会更好。如果您只想输入一个块,直到用户点击,这将是您成本最低,故障最少的解决方案。您可以忽略结果。此更新的答案是其他地方提供的非常好的do ... while循环的替代方法。

#include <stdio.h>

....

while(thing_is_happening) {
  /* do some stuff */
  for(int c = 1; c != '\n' && c != EOF; c = getchar());
  /* do some more stuff */
}

答案 1 :(得分:2)

我的图书馆中有此功能:

void    alx_wait4enter(void)
{
    int c;

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

对我有用。

您只需调用它,它就会阻塞,直到输入:

foo();
alx_wait4enter(); // Block here until enter
bar();
alx_wait4enter(); // Block again
foobar();

AFAIK,它可以在输入之前正确处理垃圾输入,甚至可以在循环或任何其他上下文中使用,甚至可以在ncurses程序中使用。

答案 2 :(得分:0)

  

可以在循环中使用scanf()函数来暂停并等待   让用户按Enter键继续?

假设标准输入连接到具有典型配置的终端,则调用从标准输入读取的任何输入函数将一直阻塞,直到按下Enter键为止。假设输入缓冲区为空。但是,如果它是非空的,则取决于缓冲区中已经存在的内容以及所使用功能的详细信息。

scanf()完全取决于您的需求,可以作为一个很好的选择,但其中涉及一些陷阱。总体而言,scanf()很难正确使用。

  

我需要的就像是RPG中的   您需要按A才能看到对话的其余部分。

如果要从标准输入中读取数据,则需要了解典型的终端行缓冲数据将进入程序。这意味着它们将存储键入的字符,直到按下[enter]或填充其缓冲区为止,然后才将数据发送到程序。结果是等待任何按键但是 [enter]都是很棘手的。

另一方面,您必须意识到在[enter]之前可能会按下其他键的可能性。在这种情况下,您可能会选择进行各种操作,但是如果您没有其他事情要做,那么您可能应该清空输入中的所有内容,直到到达换行符为止。

  

根据我的测试,此功能似乎是暂停的不佳选择。

您没有描述您进行了哪种测试,但是scanf()很难正确使用。不过,我认为这是您要执行的操作的不错选择。但是,要注意的事情之一是格式字符串中的换行符并不意味着“匹配一个换行符”。而是,格式字符串中任何一个或多个空白字符的运行都意味着“匹配零个或多个空白字符”,并且该函数直到看到 next 后才能知道它已到达空白运行的末尾。 ,非空白字符(或文件结尾)。

以下是我使用scanf等待[enter]按键的方法,并丢弃了所有内容:

char c;
int n;

c = 0;
switch(scanf("%*[^\n]%c", &c)) {
    case 1:   // a newline was scanned, corresponding to an [enter] keypress
        assert(c == '\n');
        break;
    case 0:   // the next character was a newline, or an error or EOF occurred
        n = getchar();         // consume the newline
        if (n == '\n') break;  // else it was actually error or EOF
        assert(n == EOF);
        // fall through
    case EOF: // end-of-file was reached or an I/O error occurred
        break;
    default:  // should not happen
        break;
}

scanf格式完全指定了我所描述的内容。 %*[^\n]字段描述符表示匹配一个或多个非换行符的序列,但不将它们分配到任何地方。这会吃掉下一个换行符之前的所有字符。如果成功,则%c将读取以下字符,该字符必须为换行符。

返回值scanf()告诉您真正发生的情况-具体来说,匹配并分配了多少个输入字段,或者在发生以下情况时返回特殊值EOF文件末尾或I / O错误发生,然后再进行任何匹配。特别是,如果scanf可用的第一个字符是换行符,则任何内容都不能与第一个字段匹配,因此不会从流中消耗任何内容,并且将返回0。在这种情况下,您必须尝试通过另一种机制使用流中的换行符,而getchar()在该角色中表现出色。返回值1告诉您至少匹配了一个非换行符(但未分配),然后匹配并分配了除换行符以外的其他字符。

由于格式中只有一个字段不会抑制分配,因此唯一符合的返回值为01EOF

但是,在看了一点之后,我可能会用这个替换它:

int c;

do {
    c = getchar();
while (c != '\n' && c != EOF);
// ... optionally handle the c == EOF case here ...