在C语言中等待用户输入?

5
我将尝试编写一个简单的命令,以等待用户输入。我认为这在Bash脚本中会非常有用。
以下是我的代码:
#include <stdio.h>
int main() {
  char key[1];
  puts("Press any key to continue...");
  fgets(key,1,stdin);
}

它甚至不会暂停用户输入。

我之前尝试过使用getch()(ncurses)。结果是,屏幕变空白了,当我按下一个键时,它又回到了原来的屏幕上,然后我看到了:

$ ./pause
Press any key to continue...
$

这有点符合我的要求。但是我只想要DOS/Windows中pause命令的等效命令(我使用Linux)。


5
在Bash中,您可以使用内置的 read 命令。 - Kerrek SB
getchar() - kennytm
2
https://dev59.com/rnVD5IYBdhLWcg3wGHeu - cnicutar
我尝试了 getchar()。我需要按回车键。我不想那样做。 - biggles5107
Linux有多路复用系统调用,如pollselect,以等待某些输入文件描述符。请注意,tty输入通常是内核缓冲的。 - Basile Starynkevitch
3个回答

15

从GNU C库手册中得知:

函数:char * fgets (char *s, int count, FILE *stream)

fgets 函数从流 stream 中读取字符,直到包括换行符在内,并将它们存储在字符串 s 中,添加一个空字符来标记字符串的结尾。您必须在 s 中提供 count 个字符的空间,但读取的字符数最多为 count−1。额外的字符空间用于保存字符串末尾的空字符。

因此,fgets(key,1,stdin); 读取 0 个字符并返回(即立即返回)。

请改用 getchargetline

编辑:当流上有 count 个字符可用时,fgets 也不会返回,它会等待换行符,然后读取 count 个字符,因此“任何键”可能不是本例中的正确用语。

您可以使用此示例避免行缓冲:

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int mygetch ( void ) 
{
  int ch;
  struct termios oldt, newt;
  
  tcgetattr ( STDIN_FILENO, &oldt );
  newt = oldt;
  newt.c_lflag &= ~( ICANON | ECHO );
  tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
  ch = getchar();
  tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );
  
  return ch;
}

int main()
{
    printf("Press any key to continue.\n");
    mygetch();
    printf("Bye.\n");
}

据我所知,stdin是行缓冲的,因此您无法这样做。 - ccKep
现在我明白为什么它没有等待我的输入了。但是我想要一个等待按下一个键的东西,这就是ncurses派上用场的地方。 - biggles5107
1
请查看链接,底部的代码对我来说运行良好。(编辑原始答案,包含完整代码) - ccKep

2
我不确定如何在帖子下添加评论,所以这并不是一个答案,而是一条评论。
在Linux中,标准输入是有缓冲的,因此您需要刷新它,这就是在终端上按“Enter”所做的操作。似乎您想从未缓冲的流中读取,即您想立即响应按键(无需显式刷新)。
您可以使用文件描述符创建自己的未缓冲流,然后使用“getc”从中读取,您可能需要使用termios来设置未缓冲的输入,正如其他人所建议的那样。

在答案/问题下应该有一个框,您可以在其中输入评论。 - biggles5107
虽然对我来说,我只能在自己的问题上做到这一点。 - biggles5107
2
您需要一定的声望才能够发表评论(可能是50个 - 我记不清了)。 - Steve Walsh

1
这是我在Windows 10上使用的一个简单方法:
#include <stdlib.h>

void pause(void);

int main(void)
{
    printf("Testing pause.");
}

void pause(void)
{
    system("pause");
}

问题在于它仅运行了Shell命令“pause”,正如我在OP中所解释的那样,该命令在Linux上不存在。我正在尝试自己实现这个功能。 - biggles5107

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接