如何使程序在用户未输入任何内容时执行某项操作

huangapple go评论85阅读模式
英文:

How to make a program do something if the user doesn't input anything

问题

I have a bigger project in mind, but I need the answer for this little thing to add to the project.

This is my example code:

#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;
}

The idea of this code is that an infinite loop exists which prints the current value of m indefinitely. Only when the user inputs a value does the message printed change. But the program doesn't wait for an input, basically it takes no input as an instruction to keep doing what it's doing, and if an input is, in fact, received, the message changes.

In reality, this doesn't happen because getch() makes the program stop until an input is received. getch() is somewhat what I want because, unlike cin, it doesn't wait for the user to press enter, but it does wait for something.

So my question is: How do I make a program do the same thing over and over again without stopping, and when an input is received (without having to stop and ask for the input), the output changes?

So my question is: How do I make a program do the same thing over and over again without stopping, and when an input is received (without having to stop and ask for the input), the output changes?

I found getch() and thought it was useful because it doesn't wait for the user to press enter, but it needs an input to continue with the program.

I'm on QT if it matters.

英文:

I have a bigger project in mind, but I need the answer for this little thing to add to the project.

This is my example code:

#include &lt;iostream&gt;
#include &lt;conio.h&gt;
using namespace std;

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

The idea of this code is that and infinite loop exists which prints the current value of m indefinitely. Only when the user inputs a value does the message printed change. But the program doesn't wait for an input, basically it take no input as an instruction to keep doing what it's doing, and if an input is in fact received, the message changes.

In reality this doesn't happen because getch() makes the program stop until an input is received. getch() is somewhat what I want because, unlike cin, it doesn't wait for the user to press enter, but it does wait for something.

So my question is: How do I make a program do the same thing over and over again without stopping, and when an input is received (without having to stop and ask for the input) the output changes?

So my question is: How do I make a program do the same thing over and over again without stopping, and when an input is received (without having to stop and ask for the input) the output changes?

I found getch() and thought it was useful because is doesn't wait for the user to press enter, but it needs an input to continue with the program.

I'm on QT if it matters.

答案1

得分: 0

以下是您代码中需要翻译的部分:

  • 首先,我要指出您代码中的一些问题:
    • 在使用 cout 输出到控制台后,您立即调用 System&quot;cls&quot;;,这会清除您已经打印到控制台的内容。
    • 您可以将一系列 if 语句改为 cout &lt;&lt; &quot;m is &quot; &lt;&lt; m &lt;&lt; endl;

现在回到您的问题。我必须解释很多内容,因为您要使用 getch() 来完成的操作最好通过多线程方法来实现,因为 getch() 会锁定当前线程以等待输入,而您无法在当前线程上继续执行以不断显示输入并等待输入。还有其他选择,但如果您要坚持使用 getch(),这是其中一种方法。

让我们分步进行。首先,您需要两个独立的执行线程,一个用于打印当前输入值,即您代码中的 int m,另一个用于获取输入。要实现这一点,我们需要一个std::thread对象,来表示第二个执行线程,因此我们将std::thread头文件包含到我们的项目中:

#include &lt;thread&gt;

现在我们需要一个函数来获取输入,以便我们可以将其传递给第二个线程并不断运行它。这可以通过匿名函数或所谓的lambda函数来最好实现:

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

请注意,我们通过引用捕获了 int m[&amp;m]),以便我们可以在另一个线程上修改它。还请注意 while 循环的条件语句,以便我们可以通过按下 q 按钮来退出循环。

我还添加了 std::chrono::sleep_for(),以降低输出速度,使您能够更好地看到输出值。在完成循环后,通过调用其 join() 方法,我们将第一个线程连接到 std::thread。作为最后一步,我将 int 修改为 atomic 以确保最小的线程安全性。当您将所有这些放在一起时,您将得到以下代码:

#include &lt;atomic&gt;
#include &lt;chrono&gt;
#include &lt;conio.h&gt;
#include &lt;iostream&gt;
#include &lt;thread&gt;

int main()
{
    std::atomic&lt;int&gt; m = 3;

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

    std::thread thread(func);

    while (m.load() != &#39;q&#39;) {
        std::cout &lt;&lt; &quot;m is &quot; &lt;&lt; m.load() &lt;&lt; std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

    thread.join();

    return 0;
}

我强烈建议您深入了解多线程和并发,如果您想深入研究。另外,另一个提示是不要在全局范围内使用 using namespace X;,因为在较大的项目中可能会导致名称解析问题,最好尽可能在需要时键入命名空间,例如使用 std::cout 而不是 cout

英文:

first off, i want to point out some issues in your code:

  • You immediately call System&quot;cls&quot;; after you output to console using cout, which clears everything you have printed to console
  • instead of chaining if statements, you can change it all to a
    cout &lt;&lt; &quot;m is &quot; &lt;&lt; m &lt;&lt; endl;

Now back to your question. i have to explain a lot since what you want to accomplish with getch() is done best in a multi-threaded approach, because getch() locks the current thread for input and you cannot progress the execution on the current thread to continually show input while also waiting for the input. there are other options but if you want to stick with getch() this is one of the ways.

let's take this in steps. first you want two separate threads of execution, one for printing the current input value which is int m in your code, and one for taking the input. To accomplish this, we need a std::thread object, to represent the second thread of execution, so we include the std::thread header to our project:

#include &lt;thread&gt;

now we need a function which takes the input so we can pass it to our second thread and continually run it. this can be best accomplished using anonymous functions or so called lambdas

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

notice how we capture int m by reference ([&amp;m]) so we can modify it on our other thread. also pay attention to the while's condition statement so we can escape the loop by pressing the q button.

i have further added std::chrono::sleep_for() so the output speed decreases and allows you to see the output values better. after we are finished with our loops, we join the std::thread by calling its join() method. for the final touch, i have modified the int to be atomic to ensure minimal thread-safety. when you put it all together you will have this:

#include &lt;atomic&gt;
#include &lt;chrono&gt;
#include &lt;conio.h&gt;
#include &lt;iostream&gt;
#include &lt;thread&gt;

int main()
{
    std::atomic&lt;int&gt; m = 3;

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

    std::thread thread(func);

    while (m.load() != &#39;q&#39;) {
        std::cout &lt;&lt; &quot;m is &quot; &lt;&lt; m.load() &lt;&lt; std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

    thread.join();

    return 0;
}

i strongly suggest reading up on multi-threading and concurrency if you want to delve any deeper. also another tip would be not to use using namespace X; at global scope since in larger projects it may cause name resolving issues, instead get accustomed to typing namespaces whenever possible, for example use std::cout instead of cout.

huangapple
  • 本文由 发表于 2023年3月20日 22:31:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/75791587.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定