Is there any method to call getline()
and, if there is no input given, not to block and waiting?
I have the following code:
while(true){
if(recv(sd, tBuffer, sizeof(tBuffer), MSG_PEEK | MSG_DONTWAIT) > 0) break;
getline(cin,send);
}
I want to wait for an input, but if I receive some data at sd
socket, I want stop waiting for the data and exit the while
. My code right now, just stucks on first iteration at getline()
. I want to evaluate getline()
, and if is no input available, go back at if
.
Is this possible?
PS: I tried with cin.peek()
, but that blocks for input too.
You should be able to do this by setting non-blocking mode on standard input, file descriptor 0:
int flags = fcntl(0, F_GETFL, 0);
fcntl(0, F_SETFL, flags | O_NONBLOCK);
Now, if there's no input available, the underlying read()
system call will return 0, and std::cin
will think that this is end of file, and set eof()
on std::cin
.
When you wish to read from standard input again, just clear()
the stream's state.
The only complicating factor here is that this makes it difficult to detect a real end-of-file condition on std::cin
. Not much a problem when standard input is an interactive terminal; but if standard input can be a file this is going to be an issue.
In that case, your only realistic option is to forego std::cin
completely, put non-blocking mode on file descriptor 0, poll()
or select()
it, to determine when there's something to read, then read()
it.
Although you could also use poll()
or select()
with std::cin
, this is going to get complicated, because you will need to explicitly check if there's anything already buffered in std::cin
's streambuf
, because that would, obviously, preempt any kind of poll()
or select()
checking; but by attempting to read something from std::cin
, you still run the risk of reading the buffered data, then attempting to read()
from the underlying file descriptor that's now in non-blocking mode, this resulting in a fake end-of-file condition.
To summarize: you need invest some additional time reading and understanding how file streams, and stream buffers work; and how file descriptors actually work, and how non-blocking mode works; in order to figure out the correct logic you will need to use.
Oh, and if you insist on going the non-blocking route with std::cin
, and getline()
, you will have no easy way to determine if the string returned by getline()
ends because getline()
actually read a newline from standard input, or it reached a premature fake-end of file condition and not the entire line of input has actually been read.
So, with non-blocking mode, and std::cin
, you'll be pretty much forced to use read()
, instead of getline()
.