Make c++ not wait for user input

大憨熊 提交于 2019-12-06 05:08:59

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 fdses)

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!