What about checking if buffer isn't empty? But code wouldn't be really portable then, because you need to make some system calls as I know. See this.
But maybe you can do it with some C code, I'll do some research and update my answer.
UPD: Ok, I did it. What you need is select function.
It could wait till stdin
is ready for read, and that's what we need.
But looks like it don't work with C++ streams, so you need to use only C code for reading.
Let's jump to definition:
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout)
Ok, we need to check only read buffer, so writefds
and errorfds
could be NULL
. And we need to check only stdin
, so nfds
is 1
(number of fds
es)
What about timeout? It's should be 0
, so we need to initialize variable struct timeval timeout
and set seconds and nanoseconds to 0 by timeout.tv_sec = 0
and timeout.tv_usec = 0
.
So, only readfds
left. It's pretty simple too: we need to initialize variable, "zero" it, and add stdin
.
It can be done with fd_set readfds
, FD_ZERO(&readfds)
and FD_SET(STDIN_FILENO, &readfds)
.
Okay, final step: function call. It should be select(1, &readfds, NULL, NULL, &timeout)
.
This would return 0
if input buffer is empty and 1
if it's not.
UPD2: Looks like it's not C++ streams, something strange happens and it breaks when buffer is empty at very first call. I'll try to catch the problem.
UPD3: Ok, Now I figured it out. Looks like you can use select
with C++ streams.
Select
has VERY strange (IMHO) feature: it resets readfds
. I'm not sure how to prevent It from doing this, so I just used one more fd_set
variable to hold it, so you need to add fd_set savefds = readfds
after readfds
initialization, and readfds = savefds
after each call. That's awful solution, but I don't know how could I improve it.
So code is:
Initialization:
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(STDIN_FILENO, &readfds);
fd_set savefds = readfds;
Timeout initialization:
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
And usage:
if (select(1, &readfds, NULL, NULL, &timeout)) {
cin >> input;
send(input);
}
readfds = savefds;
UPD4: Don't forget to include unistd.h
and cstdlib