为 getchar() 添加超时

发布于 2024-10-22 05:00:26 字数 172 浏览 1 评论 0原文

我需要在程序中为 getchar() 添加超时函数。

我该怎么做才能让我的程序到达指令 getchar() 时,只会等待一定的时间让用户进行击键,如果用户在给定的时间限制内没有进行击键,则程序会“跳过” getchar() 吗?

操作系统不支持 conio.h 库,因此 kbhit 不是一个选项。

I need to add a timeout function for getchar() in my program.

What do I do so that when my program reaches the instruction getchar(), it will only wait for a certain amount of time for the user to make a keystroke and if the user does not make a keystroke within the given time limit, the program will "skip" the getchar()?

The operating system does not support the conio.h library so kbhit is not an option.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清晨说晚安 2024-10-29 05:00:26

这通常是通过在 stdin 上使用 select() 来实现的。另一种解决方案是使用 alarm() 和虚拟 SIGALRM 处理程序来中断 getchar() 调用(但仅适用于 POSIX 系统)。

This is usually achieved by using select() on stdin. Another solution would be using alarm() and a dummy SIGALRM handler to interrupt the getchar() call (only working on POSIX systems though).

预谋 2024-10-29 05:00:26

如何在从“stdin”读取时添加超时
我发现这个问题很有帮助。

另一种方法是使用多线程。

如果您使用的是 c++11,则可以使用 condition_variable::wait_for() 作为计时器线程。原来的 getchar() 在另一个线程上阻塞。

下面是一个例子:

#include <termios.h>
#include <unistd.h>
#include <thread>
#include <chrono>
#include <iostream>

std::mutex mtx;
std::condition_variable cv;

int ch;
bool INPUT_SIGNAL = false;

void getch ( void ) {
  struct termios oldt, newt;

  tcgetattr ( STDIN_FILENO, &oldt );
  newt = oldt;
  newt.c_lflag &= ~( ICANON | ECHO );

  tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
  ch = getchar();
  tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );

  INPUT_SIGNAL = true;  

  cv.notify_one();
}

void timer ( int period ) {
    for(;;) {
        std::unique_lock<std::mutex> lck(mtx);

        cv.wait_for(lck, std::chrono::seconds(period), []{return INPUT_SIGNAL;});   

        if(INPUT_SIGNAL) {
            INPUT_SIGNAL = false;
            std::cout << ch << "\n";
        } else {
            std::cout << 0 << "\n";
        }
    }
}

int main() {
    std::thread worker(timer, 1);
    for(;;) {
        getch();
    }
    worker.join();
    return 0;
}

当有按键时,主线程会通知工作线程。

How to add a timeout when reading from `stdin`
I found this question is helpful.

Another method is using multithreading.

If you are using c++11, you can make use of condition_variable::wait_for() as a timer thread. And the original getchar() is blocking on another thread.

Here is an example:

#include <termios.h>
#include <unistd.h>
#include <thread>
#include <chrono>
#include <iostream>

std::mutex mtx;
std::condition_variable cv;

int ch;
bool INPUT_SIGNAL = false;

void getch ( void ) {
  struct termios oldt, newt;

  tcgetattr ( STDIN_FILENO, &oldt );
  newt = oldt;
  newt.c_lflag &= ~( ICANON | ECHO );

  tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
  ch = getchar();
  tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );

  INPUT_SIGNAL = true;  

  cv.notify_one();
}

void timer ( int period ) {
    for(;;) {
        std::unique_lock<std::mutex> lck(mtx);

        cv.wait_for(lck, std::chrono::seconds(period), []{return INPUT_SIGNAL;});   

        if(INPUT_SIGNAL) {
            INPUT_SIGNAL = false;
            std::cout << ch << "\n";
        } else {
            std::cout << 0 << "\n";
        }
    }
}

int main() {
    std::thread worker(timer, 1);
    for(;;) {
        getch();
    }
    worker.join();
    return 0;
}

When there is a keystroke, main thread will notify the worker thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文