Checking the stdin buffer if it's empty

There are several soutions:

poll or select with timeout of 0 - these would return immediately and result is either -1 with errno EAGAIN if no data available or number of descriptors with data (one, since you're checking only stdin).

ioctl is a swiss army knife of using descriptors. The request you need is I_NREAD:

if (ioctl(0, I_NREAD, &n) == 0 && n > 0)
    // we have exactly n bytes to read

However the correct solution is to read everything you got (using scanf) as a line, then process the result - and this works good enough with sscanf:

char buf[80]; // large enough
scanf("%79s", buf); // read everything we have in stdin
if (sscanf(buf, "%d", &number) == 1)
    // we have a number

... as long as you properly handle re-reading, strings that are longer than your buffer, and other real-life complications.


For anyone who comes here from google – easy select solution to check stdin emptyness:

fd_set readfds;
FD_ZERO(&readfds);
FD_SET(STDIN_FILENO, &readfds);
fd_set savefds = readfds;

struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;

int chr;

int sel_rv = select(1, &readfds, NULL, NULL, &timeout);
if (sel_rv > 0) {
  puts("Input:");
  while ((chr = getchar()) != EOF) putchar(chr);
} else if (sel_rv == -1) {
  perror("select failed");
}

readfds = savefds;

Needs unistd.h, stdlib.h and stdio.h.

Explanation can be found here.

UPD: Thanks DrBeco for noticing that select returns -1 on error -- error handling was added.

Actually, select returns:

  • the number of ready descriptors that are contained in the descriptor sets
  • 0 if the time limit expires
  • -1 if an error occurred (errno would be set)

Tags:

C