【问题标题】:c++ breaking out of loop by key press at any timec ++随时通过按键跳出循环
【发布时间】:2013-04-29 04:08:38
【问题描述】:

我这里有一个循环,它应该每 500 毫秒读取一次设备上的输出。这部分工作正常。但是,当我尝试引入 cin.get 来获取被按下的键“n”以停止循环时,我只得到与此时按键次数一样多的输出。如果我按任意键(除了'n')几次然后回车,我会得到更多的输出。我需要的是循环在没有任何交互的情况下一直循环,直到我想要它停止。

代码如下:

for(;;)
{
    count1++;
    Sleep(500);
    analogInput = ReadAnalogChannel(1) / 51.0;
    cout << count1*0.5 << "     " << analogInput << endl;
    outputFile << count1*0.5 << ", " << analogInput << endl;
    if (cin.get() == 'n') //PROBLEM STARTS WITH THIS INTRODUCED
        break;
};

我的输出如下(在程序中有 2 次按键才能进入这个阶段),除非我再按几个键然后回车:

0.5    0 // as expected
1      2 // as expected
should be more values until stopped

我对使用哪种类型的循环没有特别的偏好,只要它有效。

谢谢!

【问题讨论】:

  • 鉴于您已经在使用Sleep,最快的方法是将if (cin.get() == 'n') 替换为if (GetAsyncKeyState(0x4E) &amp; 0x8000)cin.get() 正在阻塞。但是,由于有 500 毫秒的延迟,循环中并没有很大一部分用于异步检查。有更好的方法可以做到这一点,但如果你按住键一会儿或者运气好的话,这会奏效。
  • 它工作得很好,但是我需要按住键一会儿,这可能会成为以后的问题。请您为我指明替代解决方案的正确方向吗?
  • 你可以在你自己的进程上附加一个钩子来监控击键并在 n 被击中时通知循环。或者,您可以在单独的线程中获得输入,这似乎是新答案的路径。

标签: c++ loops keypress infinite-loop


【解决方案1】:

cin.get() 是一个同步调用,它暂停当前执行线程,直到它获得输入字符(您按下一个键)。

您需要在单独的线程中运行循环并轮询原子布尔值,您在 cin.get() 返回后在主线程中更改它。

它可能看起来像这样:

std::atomic_boolean stop = false;

void loop() {
    while(!stop)
    {
        // your loop body here
    }
}

// ...

int main() {
    // ...
    boost::thread t(loop); // Separate thread for loop.
    t.start(); // This actually starts a thread.

    // Wait for input character (this will suspend the main thread, but the loop
    // thread will keep running).
    cin.get();

    // Set the atomic boolean to true. The loop thread will exit from 
    // loop and terminate.
    stop = true;

    // ... other actions ...

    return EXIT_SUCCESS; 
}

注意:上面的代码只是给出一个想法,它使用了 Boost 库和最新版本的标准 C++ 库。这些可能对您不可用。如果是这样,请使用您环境中的替代方案。

【讨论】:

  • 在 C++-11 中,std::thread 可用。此处无需使用 Boost。
【解决方案2】:

如果 (cin.get() == 'n')

此调用将停止您的循环,直到它收到您的密钥。在你看到发生的情况下停止你的循环。

cin.get() 会一直呆在那里,直到它收到你的击键。

【讨论】:

    猜你喜欢
    • 2021-03-31
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多