C non-blocking keyboard input

2018-12-31 10:04发布

I'm trying to write a program in C (on Linux) that loops until the user presses a key, but shouldn't require a keypress to continue each loop.

Is there a simple way to do this? I figure I could possibly do it with select() but that seems like a lot of work.

Alternatively, is there a way to catch a ctrl-c keypress to do cleanup before the program closes instead of non-blocking io?

10条回答
美炸的是我
2楼-- · 2018-12-31 10:45

On UNIX systems, you can use sigaction call to register a signal handler for SIGINT signal which represents the Control+C key sequence. The signal handler can set a flag which will be checked in the loop making it to break appropriately.

查看更多
千与千寻千般痛.
3楼-- · 2018-12-31 10:45

There is no portable way to do this, but select() might be a good way. See http://c-faq.com/osdep/readavail.html for more possible solutions.

查看更多
裙下三千臣
4楼-- · 2018-12-31 10:53

The curses library can be used for this purpose. Of course, select() and signal handlers can be used too to a certain extent.

查看更多
唯独是你
5楼-- · 2018-12-31 10:56

Here's a function to do this for you. You need termios.h which comes with POSIX systems.

#include <termios.h>
void stdin_set(int cmd)
{
    struct termios t;
    tcgetattr(1,&t);
    switch (cmd) {
    case 1:
            t.c_lflag &= ~ICANON;
            break;
    default:
            t.c_lflag |= ICANON;
            break;
    }
    tcsetattr(1,0,&t);
}

Breaking this down: tcgetattr gets the current terminal information and stores it in t. If cmd is 1, the local input flag in t is set to non-blocking input. Otherwise it is reset. Then tcsetattr changes standard input to t.

If you don't reset standard input at the end of your program you will have problems in your shell.

查看更多
登录 后发表回答