如何在C ++中创建一个运行时间计数器并允许同时进行用户输入的循环(非阻塞用户输入)

时间:2015-02-22 08:08:49

标签: c++ nonblocking kbhit

所以,我想要做的是在C ++中创建一个函数,允许用户在一段时间内将任何东西和所有东西都输入一个字符串(比如十分钟(甚至十分钟)一个))(并保留他们输入的所有内容, btw。我试图设计一款游戏来帮助NaNoWriMo参与者或作者推动他们写作,所以保持一切都是必不可少的)然后不允许再附加任何输入。这听起来很容易,但谷歌的五个小时证明不然。

首先,我想我可以反复追加,直到时间用完或什么的。观察:

int main() //testing
{
    string str;
    string app = " ";
    getline(cin, app);

    for (int i = 0; i <= 3; i++)
    {
        Sleep(5000);
        cout << i << endl;
        str = " ";
        getline(cin, str);
        app.append(str);
    }

    cout << app;
}

然后我意识到, duh,循环不会再次检查条件,直到用户按下回车键。麻烦。与我对角色的聪明想法相同。无论用户输入另一个字符多长时间,我都需要一个循环,该循环会更新每个键入的字符(或每隔一秒)。

所以,那时我就像,#34;那么,停在每个空间并更新时间应该可以运作得很好,是吗?&#34;

这时我开始发现C ++在解析字符串时不能很好地运行,或者在获取字符串时读取输入。我想要附加每个字符,因为很容易找到一个空格,但仍然等待用户。

感到沮丧,我想知道是否有办法在获取用户输入时同时运行程序,以便一旦用完(使用时间(null),时间过去,时间(null)和减去两个变量以获得经过的秒数。

原来,有! (我知道已经,考虑到使用这个原理的所有计算机程序和游戏,但我对编程很新(我最后学习了函数星期三,给你一个想法),所以我不知道是什么。)

我偶然发现的第一个功能是诅咒和诅咒,但我很快发现,对于我想要做的事情来说,这真的不是一个可行的选择(因为我听说这对Cout来说确实很有趣)。

然后我偶然发现了kbhit,它识别键盘上按键的时间。 This blog似乎很有希望,也许我想做什么,但我不确定它写的是什么语言。 。 。我所知道的是它与我的C ++ IDE不能很好地配合。我不知道如何让它与C ++一起玩得很好。

所以,重申我的想法:

包含同时执行时间计数器和用户输入(到字符串)的循环,但在时间用完时终止(停止让用户进一步输入字符串)。(所有这些都没有对我的程序的其余部分做有趣的事情,比如ncurses会。)

此外:我运行Windows 8(我存在的祸根),我使用Code :: Blocks作为我的IDE。

或者,如果你已经得到它,这个问题的某个地方已经得到了回答。那真的很棒。只是让我感到愚蠢,我无法找到它。

(这是我沿途看到的一些地方:

User input while program still running

How do I read input from standard input until a space or a tab is pressed?

Capture characters from standard input without waiting for enter to be pressed

(我试图创造的游戏,(这完全不是很远;我昨晚开始),万一你好奇:https://github.com/Rowan-Law/Dungeon-Crawl/blob/master/Source%20Code

3 个答案:

答案 0 :(得分:1)

您可能想要创建一个时间线程,然后继续更新字符串,直到返回时间线程

答案 1 :(得分:0)

多线程是解决方案。在基本级别上,使用std::cin的C ++控制台应用程序仅在输入时更新(正如我和Christian Hackl所指出的那样),因此如果没有线程,我想做的事情是不可能的。

我知道这个问题已经很老了,但是我希望这个答案可以节省一些其他新手大量的时间,以便在网络上寻找不存在的答案!

答案 2 :(得分:0)

这是使用线程在C ++ 17中获得所需近似结果的方式。唯一的麻烦是用户仍然可以在时间限制后输入内容,只是不会保存。

#include <atomic>
#include <chrono>
#include <iostream>
#include <istream>
#include <mutex>
#include <ostream>
#include <string>
#include <thread>

std::atomic_bool done = false;
std::mutex cout_mutex{};

void Timing(std::chrono::seconds length) {
    auto start = std::chrono::steady_clock::now();
    auto end = start + length;
    auto now = std::chrono::steady_clock::now();
    while(now < end) {
        now = std::chrono::steady_clock::now();
        done = false;
    }
    done = true;
    {
        std::scoped_lock<std::mutex> lock(cout_mutex);
        std::cout << "\nTime's up! Any unsaved input will be lost." << std::endl;
    }
}

int main() {
    std::string str{};
    std::string app{};

    using namespace std::literals::chrono_literals;
    //This can be any duration you want.
    std::thread t = std::thread(Timing, 30s);
    t.detach();
    while(!done) {
        std::getline(std::cin, str);
        if(!done) {
            app.append(str + '\n');
        }
    }
    std::cout << app;
}