windows 如何让程序在用户没有输入任何东西的情况下做一些事情

r7knjye2  于 2023-03-24  发布在  Windows
关注(0)|答案(1)|浏览(117)

我心中有一个更大的项目,但我需要这个小东西的答案添加到项目中。
这是我的示例代码:

#include <iostream>
#include <conio.h>
using namespace std;

int main()
{
    int m=3;
    while (true){
        if (m==1){
            cout<<"m is 1"<<endl;
            system("cls");
        }
        if (m==2){
            cout<<"m is 2"<<endl;
            system("cls");
        }
        if (m==3){
            cout<<"m is 3"<<endl;
            system("cls");
        }
        m=getch();
    }
    return 0;
}

这段代码的思想是存在一个无限循环,它会无限期地打印m的当前值。只有当用户输入一个值时,打印的消息才会改变。但是程序不会等待输入,基本上它不接受任何输入作为继续执行它正在做的事情的指令,如果实际上收到了输入,消息就会改变。
在现实中,这不会发生,因为getch()使程序停止,直到收到输入。getch()是我想要的,因为,不像cin,它不等待用户按下回车键,但它确实等待一些东西。
所以我的问题是:我如何让一个程序不停地重复做同样的事情,当一个输入被接收时(不必停下来要求输入),输出就改变了?
所以我的问题是:我如何让一个程序不停地重复做同样的事情,当一个输入被接收时(不必停下来要求输入),输出就改变了?
我发现了getch(),并认为它很有用,因为它不会等待用户按回车键,而是需要一个输入来继续程序。
如果有关系的话,我会保密的。

jv4diomz

jv4diomz1#

首先,我想指出代码中的一些问题:

  • 在使用cout输出到控制台后,立即调用System"cls";,这将清除所有已打印到控制台的内容
  • 您可以将其全部更改为cout << "m is " << m << endl;,而不是链接if语句

现在回到您的问题,我必须解释很多,因为您希望用getch()完成的任务最好是在多线程方法中完成,因为getch()锁定了当前线程的输入,并且您无法在当前线程上继续执行以在等待输入的同时继续显示输入。还有其他选择,但如果你想坚持使用getch(),这是其中一种方法。
让我们分步骤来做。首先,你需要两个独立的执行线程,一个用于打印 * 当前输入值 *,在你的代码中是int m,另一个用于获取输入。为了实现这一点,我们需要一个std::thread对象,来表示第二个执行线程,所以我们在我们的项目中包含std::thread头文件:

#include <thread>

现在我们需要一个函数,它接受输入,这样我们就可以把它传递给第二个线程并继续运行它。这可以最好地使用匿名函数或所谓的lambdas来完成

auto func = [&m]() 
    {
        while (m != 'q')
        {
            m = _getch();
        }
    };

注意我们如何通过引用([&m])捕获int m,以便我们可以在其他线程上修改它。还请注意while的条件语句,以便我们可以通过按下q按钮来逃避循环。
我进一步添加了std::chrono::sleep_for(),因此输出速度降低,并允许您更好地查看输出值。在我们完成循环后,我们通过调用join()方法来加入std::thread。最后一点,我将int修改为atomic以确保最小的线程安全性。当您将其放在一起时,您将得到:

#include <atomic>
#include <chrono>
#include <conio.h>
#include <iostream>
#include <thread>

int main()
{
    std::atomic<int> m = 3;

    auto func = [&m]() {
        while (m.load() != 'q')
        {
            m.store(_getch());
        }
    };

    std::thread thread(func);

    while (m.load() != 'q') {
        std::cout << "m is " << m.load() << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

    thread.join();

    return 0;
}

我强烈建议阅读多线程和并发性,如果你想深入研究的话。另外,另一个技巧是不要在全局范围内使用using namespace X;,因为在较大的项目中,它可能会导致名称解析问题,而是习惯于尽可能输入名称空间,例如使用std::cout而不是cout

相关问题