gpt4 book ai didi

C++ 中断或取消 getch();

转载 作者:太空宇宙 更新时间:2023-11-04 13:07:57 33 4
gpt4 key购买 nike

我有一个简单的计时器。它在一个与主线程分开的线程中运行的函数中。使用 std::future,该函数返回一个简单的 bool 值,表示计时器是否达到特定数字。

我正在使用 getch(); 查看用户是否按下了字母键。

如果计时器返回真,即它命中了指定的数字,我需要取消getch();并转到代码中的下一步。进入下一步很容易。

已经 2 周了,我找不到解决问题的方法。

问题: 我究竟该如何中断或取消对 getch(); 的调用?这可能吗?

我正在使用 getch(); 来识别按下了哪些字母键。

C++11 Visual Studio。

最佳答案

操作系统必须提供对键盘的访问。因此,例如在 Windows 上,最好的方法可能是按照操作系统的术语处理输入,如 here 所述。 .

使用标准的 c++ 库函数,可以从 std::cin 流中读取字符。问题在于,这些字符仅在用户按下 Enter(同时添加换行符 \n 字符)后才从操作系统传递。

如果您可以忍受在键入一个字符后按回车键的需要,那么下面的代码就可以工作了。该程序执行 get()在一个单独的线程中,这样如果没有按下任何键或者如果 Enter 没有被按下并且只使用标准的 c++11,它就不会阻塞程序。但是,除非用户键入 qsends the EOF,否则该程序不会完成(即加入线程) .

#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>

std::condition_variable cv{};
std::mutex mtx;
std::queue<char> char_queue{};
bool quit{false};

void add_chars_to_queue()
{
char c{};
for(;;) {
c = static_cast<char>(std::cin.get());
if(!std::cin) {
std::unique_lock<std::mutex> lck{mtx};
quit = true;
cv.notify_all();
return;
}
if(c == 'q' || c == 'Q') {
std::unique_lock<std::mutex> lck{mtx};
quit = true;
char_queue.push(c);
cv.notify_all();
return;
}
if(c == '\n')
continue;
std::unique_lock<std::mutex> lck{mtx};
char_queue.push(c);
cv.notify_all();
}
}


std::string get_key_or_wait(std::chrono::system_clock::duration d)
{
std::unique_lock<std::mutex> lck{mtx};
for(int i{10}; i > 0; --i) {
cv.wait_for(lck, d / 10., []() {return quit || !char_queue.empty(); });
if(!char_queue.empty())
break;
if(quit)
return{"Quitting.\n"};
std::cout << "Countdown at " << i << '\n';
}
std::string return_string{};
if(!char_queue.empty()) {
return_string += "Obtained a character from the stream before the timer ran out. Character was: ";
return_string += char_queue.front();
char_queue.pop();
}
else {
return_string = "Timer ran out.";
}

return return_string;
}

int main()
{
std::thread get_chars{[]() {add_chars_to_queue(); }};

std::cout << "Type q to exit.\n";
for(int i{}; i < 3; ++i) {
{
std::lock_guard<std::mutex> lck{mtx};
if(quit)
break;
}
std::cout << "Waiting for key press followed by <enter>.\n";
std::cout << get_key_or_wait(std::chrono::seconds(10)) << '\n';
}

get_chars.join();
return 0;
}

输出:

Type q to exit.
Waiting for key press followed by <enter>.
Countdown at 10
Countdown at 9
Countdown at 8
a
Obtained a character from the stream before the timer ran out. Character was: a
Waiting for key press followed by <enter>.
Countdown at 10
Countdown at 9
Countdown at 8
Countdown at 7
Countdown at 6
Countdown at 5
Countdown at 4
Countdown at 3
Countdown at 2
Countdown at 1
Timer ran out.
Waiting for key press followed by <enter>.
Countdown at 10
Countdown at 9
Countdown at 8
bCountdown at 7
Countdown at 6
Countdown at 5

Obtained a character from the stream before the timer ran out. Character was: b
q

关于C++ 中断或取消 getch();,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41368759/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com