【问题标题】:C| how to check if my input buffer(stdin) is empty?C|如何检查我的输入缓冲区(stdin)是否为空?
【发布时间】:2016-04-05 13:41:06
【问题描述】:

我想知道如何检查我的输入缓冲区(可能称为stdin)是否为空。 如果缓冲区为空,我不希望程序停止,并且我不希望输入一定以\n 结尾,因此仅使用scanf 是不够的。

我尝试在谷歌和这个网站上搜索,但没有足够的答案。 我尝试像这样使用feof(stdin)

int main()
{
    char c,x;
    int num;
    scanf("%c",&c);
    scanf("%c",&x);
    num=feof(stdin);
    printf("%d",num);
}

但无论输入如何,它所做的只是打印 0。在第二个 scanf 之后添加 fflush(stdin) 给出了相同的结果。 其他答案建议使用 select 和 poll,但我找不到这些功能的任何解释。

其他一些论坛告诉我使用getchar(),但我认为他们误解了我的问题。

如果您建议我使用 select/poll,您能否添加有关如何使用它们的说明?

【问题讨论】:

  • 查看如何在 SO 上提问。这里没有代码...
  • 从专用线程中的输入读取。
  • '我尝试在 google 和这个网站上搜索,但没有足够的答案' - 请告诉我们您使用的 seach 字符串,以及为什么返回的链接不够。
  • 这不是教程网站。
  • '能否请您添加一个关于如何使用这些的解释'和'这是一个一般性问题,它不适用于特定代码'是相互排斥的。

标签: c input buffer stdin


【解决方案1】:

解决这个问题的代码如下:

fseek (stdin, 0, SEEK_END);
num = ftell (stdin);

fseek 会将指针放在stdin 输入缓冲区的末尾。 ftell 将返回文件的大小。

【讨论】:

  • fseek()ftell()FIFOS a.out < file 上不起作用。错误:无效搜索。返回 -1。
  • 是的,这不起作用,而且似乎总是返回 -1。
  • 你在哪里测试的?在 Windows 上,它对 a.out
  • 我刚刚发现它在 Windows 上进行管道传输时无法正常工作。所有管道命令同时启动,因此在“c1 | c2”中,c2 的标准输入为空,直到 c1 向其中写入内容。 c2 中的上述检查将产生 false 并且 c2 将立即停止。但是 c2 必须阻塞并等待标准输入。就我而言,要么我期待标准输入,要么我不期待,因为参数告诉我。
【解决方案2】:

如果您不想阻塞空的 stdin,您应该能够将其 fcntl 设置为 O_NONBLOCK 并将其视为任何其他非阻塞 I/O。此时,对 fgetc 之类的调用应立即返回,如果流为空,则返回值或 EAGAIN

【讨论】:

  • 好吧,我有点放弃了这件事。相反,我现在试图详细学习整个标准 c 输入/输出,我的意思是我想学习的不仅仅是“只是 scanf 来获取东西”。就像我想知道什么是标准输入以及输入是如何工作的。介意向我推荐任何学习资源吗?
【解决方案3】:
int ch = getc(stdin);
if (ch == EOF)
    puts("stdin is empty");
else
    ungetc(ch, stdin);

试试这个,添加ungetc(ch, stdin);以消除副作用。

【讨论】:

  • 这并不能解决问题,因为getc() 会阻塞。
【解决方案4】:

您可以使用select() 来处理阻塞问题,并且手册页select(2) 有一个不错的示例来轮询stdin。这仍然不能解决需要行分隔符 ('\n') 的问题。这实际上是由于终端处理输入的方式。

在 Linux 上,您可以使用 termios,

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

// immediate mode getchar().
static int getch_lower_(int block)
{
    struct termios tc = {};
    int status;
    char rdbuf;
    // retrieve initial settings.
    if (tcgetattr(STDIN_FILENO, &tc) < 0)
        perror("tcgetattr()");
    // non-canonical mode; no echo.
    tc.c_lflag &= ~(ICANON | ECHO);
    tc.c_cc[VMIN] = block ? 1 : 0; // bytes until read unblocks.
    tc.c_cc[VTIME] = 0; // timeout.
    if (tcsetattr(STDIN_FILENO, TCSANOW, &tc) < 0)
        perror("tcsetattr()");
    // read char.
    if ((status = read(STDIN_FILENO, &rdbuf, 1)) < 0)
        perror("read()");
    // restore initial settings.
    tc.c_lflag |= (ICANON | ECHO);
    if (tcsetattr(STDIN_FILENO, TCSADRAIN, &tc) < 0)
        perror("tcsetattr()");
    return (status > 0) ? rdbuf : EOF;
}

int getch(void)
{
    return getch_lower_(1);
}

// return EOF if no input available.
int getch_noblock(void)
{
    return getch_lower_(0);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-27
    • 2012-02-03
    • 1970-01-01
    • 2013-12-16
    • 2011-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多