C| how to check if my input buffer(stdin) is empty

2019-04-02 20:13发布

I want to know how to check if my input buffer(perhaps its called stdin) is empty or not. i dont want the program to stop if the buffer is empty, and i dont want the input to necessarily end with '\n', therefore just using scanf is not enough.

i tried searching on google and on this website but no answer was enough. i tried using feof(stdin) like this:

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

but all it did was printing 0 no matter the input. adding fflush(stdin) after the second scanf gave the same result. other answers suggested using select and poll but i couldnt find any explanations for those functions. some other forum told me to use getchar() but i think they misunderstood my question.

on the google search i tried: C how to check input buffer empty, C stdin empty, c "input buffer" check empty. this is a general question, its not for a specific code so it doesnt matter why i need it.

**if you suggest i use select/poll, could you please add an explanation about how to use those?

4条回答
forever°为你锁心
2楼-- · 2019-04-02 20:41

You can use select() to handle the blocking issue and the man page select(2) has a decent example that polls stdin. That still doesn't address the problem of needing a line-delimiter ('\n'). This is actually due to the way the terminal handles input.

On Linux you can use 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);
}
查看更多
成全新的幸福
3楼-- · 2019-04-02 20:42
int ch = getc(stdin);
if (ch == EOF)
    puts("stdin is empty");
else
    ungetc(ch, stdin);

Try this, ungetc(ch, stdin); is added to eliminate the side effect.

查看更多
Viruses.
4楼-- · 2019-04-02 20:43

Here is the code for solving this:

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

fseek will put the pointer at the end of the stdin input buffer. ftell will return the size of file.

查看更多
爷、活的狠高调
5楼-- · 2019-04-02 20:53

If you don't want to block on an empty stdin you should be able to fcntl it to O_NONBLOCK and treat it like any other non-blocking I/O. At that point a call to something like fgetc should return immediately, either with a value or EAGAIN if the stream is empty.

查看更多
登录 后发表回答