Cin without waiting for input?

For the project I'm working on, I need a program to get input from the user, but as long as they enter something, the program can continue in a loop.

For instance:
while (true) { if (userInput == true) { cin >> input } //DO SOMETHING } 

This would mean that //DO SOMETHING will happen every cycle, without clicking on the user, a million times.

My solution used to create my own input using kbhit() and getch() from conio.h, but it got really dirty and I don't like to use conio.h for mobility reasons, etc. In addition, he does not need to use cin purpose, because there is a good chance that it just won’t work with him, so any good solution that does not require me to enter my own resources with a β€œnot very good” library would be highly appreciated.
+5
source share
3 answers

It is sad that there is no simple portable way of checking asynchronously if a key has been deleted. But I think the standard committee carefully evaluated the pros and cons.

If you don't want to rely on third-party event management libraries, and if multithreading is excessive, one alternative could be your own version of kbhit() with conditional compilation for the environments you want to support:

  • If your conio.h supports kbhit (), just use it.
  • for windows you can refer to _ kbhit ()
  • for linux and posix, you can use Matthieu's answer or look here for Morgan Mattews code

This is not the most academic answer, but it is pragmatic.

+1
source

Disclaimer: It seems to work with gcc on Linux, but for some reason it does not work with VC ++ on Windows. The specifications seem to provide a lot of scope for implementation here, and VC ++ definitely uses it ...

Several functions are available on either std::basic_istream or its base std::basic_streambuf .

To find out if there is any character to enter, you can call in_avail in std::basic_streambuf :

 if (std::cin.rdbuf() and std::cin.rdbuf()->in_avail() >= 0) { } 

in_avail gives you the number of characters available without blocking, it returns -1 if there is no such character. After that, you can use the usual "formatted" read operations, such as std::cin >> input .

Otherwise, for unformatted reads, you can use readsome from std::basic_istream , which returns up to N characters available without blocking:

 size_t const BufferSize = 512; char buffer[BufferSize]; if (std::cin.readsome(buffer, BufferSize) >= 1) { } 

However, it is noted that the implementation of this method is greatly changed, so for a portable program this may not be so useful.

Note: as noted in the comment, the in_avail approach may be spotty. I confirm that it can work , however first you need to use the unclear feature of IO C ++ streams: std::ios_base::sync_with_stdio(false) , which allows C ++ streams to buffer input (and thus steal it from buffers C stdio).

+2
source

This may require multithreading. I usually hesitate to suggest this because multithreading raises many potential problems that can be difficult to debug, but in this case they can be isolated quite easily. I imagine something like this:

 #include <atomic> #include <chrono> #include <iostream> #include <thread> int main() { std::atomic<bool> interrupted; int x; int i = 0; do { interrupted.store(false); // create a new thread that does stuff in the background std::thread th([&]() { while(!interrupted) { // do stuff. Just as an example: std::cout << i << std::flush; std::this_thread::sleep_for(std::chrono::milliseconds(100)); } }); std::cin >> x; // when input is complete, interrupt thread and wait for it to finish interrupted.store(true); th.join(); // apply x, then loop to make new thread to do stuff i = x; } while(x != -1); // or some other exit condition } 

At first glance, this looks somewhat wasteful because it continues to spawn and throw threads, but user input requires, in computational terms, an eternity, so overhead should not be prohibitive. More importantly, it has the advantage that you can avoid any assumptions about selling data, because the only means of communication between the main (input) loop and the background thread is the atom interrupt flag, and application x for general data when the thread is not It works that can chase the main circuit.

+2
source

Source: https://habr.com/ru/post/1209617/


All Articles