8

I searched but did not get a relevant answer to this question, i am working on a linux machine, i wanted to check if the standard input stream contains any character, without removing the characters from the stream.

51k
  • 1,381
  • 3
  • 12
  • 22
  • 1
    C++ or C? Your question is tagged with both. – Carl Norum Apr 26 '13 at 04:52
  • 3
    I am not sure that your question has a well defined meaning. Imagine the *stdin* being a pipe (from a command which takes ages to spit its first character on its *stdout*). What you could do is call [poll(2)](http://man7.org/linux/man-pages/man2/poll.2.html) using `STDIN_FILENO` (i.e. 0) as a file descriptor. You then check if *stdin* is readable... (i.e. that [read(2)](http://man7.org/linux/man-pages/man2/read.2.html) won't block). – Basile Starynkevitch Apr 26 '13 at 04:52

2 Answers2

6

You might want to try select() function, and wait for having data into the input stream.

Description:

select() and pselect() allow a program to monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready" for some class of I/O operation (e.g., input possible). A file descriptor is considered ready if it is possible to perform the corresponding I/O operation (e.g., read(2)) without blocking.

In your case, the file descriptor will be stdin

void yourFunction(){
    fd_set fds;
    struct timeval timeout;
    int selectRetVal;

    /* Set time limit you want to WAIT for the fdescriptor to have data, 
       or not( you can set it to ZERO if you want) */
    timeout.tv_sec = 0;
    timeout.tv_usec = 1;

    /* Create a descriptor set containing our remote socket
       (the one that connects with the remote troll at the client side).  */
    FD_ZERO(&fds);
    FD_SET(stdin, &fds);

    selectRetVal = select(sizeof(fds)*8, &fds, NULL, NULL, &timeout);

    if (selectRetVal == -1) {
        /* error occurred in select(),  */
        printf("select failed()\n");
    } else if (selectRetVal == 0) {
        printf("Timeout occurred!!! No data to fetch().\n");
        //do some other stuff
    } else {
        /* The descriptor has data, fetch it. */
        if (FD_ISSET(stdin, &fds)) {
            //do whatever you want with the data
        }
    }
}

Hope it helps.

Cacho Santa
  • 6,846
  • 6
  • 41
  • 73
  • 3
    Thanks for an instant rply, however, i do not want to wait for the input stream to have the data, Its just that, if the stream has data, i need to do some processing, if it does not have data, do some other processing. The code should not wait for the input, – 51k Apr 26 '13 at 05:11
  • I still think this could help @51k, let me put an example. – Cacho Santa Apr 26 '13 at 05:18
  • I had to use `0` instead of `stdin` for gcc c++ – Bryce Guinta Jul 08 '18 at 00:10
5

cacho was on the right path, however select is only necessary if you're dealing with more than one file descriptor, and stdin is not a POSIX file descriptor (int); It's a FILE *. You'd want to use STDIN_FILENO, if you go that route.

It's not a very clean route to take, either. I'd prefer to use poll. By specifying 0 as the timeout, poll will return immediately.

If none of the defined events have occurred on any selected file descriptor, poll() shall wait at least timeout milliseconds for an event to occur on any of the selected file descriptors. If the value of timeout is 0, poll() shall return immediately. If the value of timeout is -1, poll() shall block until a requested event occurs or until the call is interrupted.

struct pollfd stdin_poll = { .fd = STDIN_FILENO
                           , .events = POLLIN | POLLRDBAND | POLLRDNORM | POLLPRI };
if (poll(&stdin_poll, 1, 0) == 1) {
    /* Data waiting on stdin. Process it. */
}
/* Do other processing. */
autistic
  • 1
  • 3
  • 35
  • 80
  • just a heads up, but first time i clicked on the poll link, I was redirected here: http://www3.opengroup.org/ ... secnond time, here: http://pubs.opengroup.org/onlinepubs/009695399/functions/poll.html (which seems to be what you intended) – Chris Nov 02 '18 at 13:43