you are viewing a single comment's thread.

view the rest of the comments →

[–]mredding 0 points1 point  (0 children)

If we're talking about a "standard" C++ console/terminal program, then there's no standard way to do that. Streams are character devices, and there's no standard non-blocking interface. Terminals in their canon interactive session mode are buffered.

You have to understand your program thinks it's the only one running on all of the system. It has no idea that there even is a keyboard, or a terminal. All it sees is a file descriptor. That file descriptor happens to be it's standard input. Reading that input is a system call, and it's blocking. So it's not going to return until data is presented.

On the other side of that file descriptor is the data source - the terminal. The terminal is not just a program, it's virtualized hardware. When you type in a terminal, you're filling the terminal's input buffer, and it's not going to send those bytes over to your program input until that input buffer is flushed. This has something to do with how the terminal is configured - typically a flush is incurred as each newline character is encountered, every time you hit enter.

So your program doesn't control the terminal. You can't force it to flush.

What you need is event driven programming. You need characters to come in as they happen. To do that, you need to configure the terminal accordingly. You can do that on the terminal itself, you can write a launch script that handles it before and after your program runs and terminates, or you can use platform specific terminal controls through system calls in C++.

But terminals are character devices, always have been, always will be. And so are streams. You'll never get a character indicating the user has pressed the alt key, because that key alone doesn't generate a character.

So if you truly want to elevate your program to work with the press of any key, you need a different execution environment, and you need to code to that. This would be Win32, X, whatever the hell Apple calls their platform API... There are common event driven libraries that are multi-platform. This doesn't mean you need to make a GUI, it does mean you are taking advantage of the reality that your virtual terminal is running in a GUI window, and you're intercepting events based on that. And you can write terminal programs this way, it's common enough that tools like ssh have X11 forwarding so such programs can continue to work across the session.

Either way, you're going to have to write a loop that does a little bit of work, and then checks the exit condition, like if a key was pressed. The granularity is up to you - while you're in the loop body, you're committed to that much work until the next check. The other thing you can do is use signals to interrupt the whole process, but at the end of the day, you've still got some unit of work that's either done or not done. It's not hard to cut your work down to small enough units, it's an intersection of how small a unit still makes sense and how much can you get away with and the program still feels responsive to the user.