在C++中是否有一个像样的等待函数?

49 c++ wait

我在C++中学到的第一件事就是

#include <iostream>
int main()
{
    std::cout<<"Hello, World!\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

只会出现并迅速消失而不会停顿.为了防止这种情况,我不得不去记事本,然后保存

helloworld.exe
pause
Run Code Online (Sandbox Code Playgroud)

ASE

helloworld.bat
Run Code Online (Sandbox Code Playgroud)

当我需要创建一堆小测试程序时,这很乏味,最终我只是把while(true);我的大部分测试程序放在最后,这样我才能看到结果.我可以使用更好的等待功能吗?

Dea*_*ead 64

您可以要求用户在关闭程序之前按Enter键...这样的工作.

#include <iostream>
int main()
{
  std::cout << "Hello, World\n";
  std::cin.ignore();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

cin读入用户输入,cin的.ignore()函数告诉程序忽略输入.一旦用户点击进入,该程序将继续.

链接

  • 但是**请*不要*这样做**!! 这是一个_massive_抽象泄漏,完全破坏了程序的可链接性.学会正确操作命令行环境.例如`cmd/K myprogram.exe` (15认同)
  • 抽象泄漏是什么意思?@LightnessRacesinOrbit (3认同)

Lig*_*ica 48

很多人都建议使用POSIX sleep,Windows Sleep,Windows system("pause"),C++ cin.get()...... getch()从大约20世纪20年代后期开始,就有了DOS .

不要做任何这些.

这些解决方案都不会通过我的团队中的代码审查.这意味着,如果您提交此代码以包含在我们的产品中,您的提交将被阻止,并且您将被告知去寻找另一种解决方案.(有人可能会说,当你只是一个业余爱好者玩耍时事情并不那么严重,但我建议在你的宠物项目中养成良好的习惯会使你成为商业组织中有价值的专业人士,并让你受雇. )

保持控制台窗口打开,以便您可以阅读程序的输出,这不是您的程序的责任!当您在程序结束时添加wait/sleep/block时,您违反了单一责任原则,造成了大量的抽象泄漏,并且删除了程序的可重用性/可链接性.它不再需要输入并提供输出 - 它会因瞬态使用原因而阻塞.这非常不好.

相反,您应该配置环境以在程序完成工作后保持提示打开.你的批处理脚本包装是一个很好的方法!我可以看到必须保持手动更新是多么烦人,你不能从IDE调用它.您可以使脚本将程序的路径作为参数执行,并将IDE配置为直接调用它而不是程序.

临时的快速启动方法是将IDE的运行命令cmd.exe <myprogram>更改<myprogram>cmd.exe /K <myprogram>.该/K开关cmd.exe 作及时保持开放在给定路径的程序已经终止后.这比批处理脚本解决方案稍微麻烦一点,因为现在你必须exit在读完程序的输出时键入或点击红色的"X",而不是仅仅打击空格键.


我假设使用IDE,因为否则你已经从命令提示符调用了,这首先不是问题.此外,我假设使用Windows(基于问题中给出的细节),但这个答案适用于任何平台......顺便提一下,这是一半的观点.

  • 这似乎有点矫枉过正 - 我理解一般观点,但对于只是在 IDE 中寻找“睡眠”功能和集成的新用户来说,这个建议似乎令人困惑(而且为时过早) (5认同)
  • @Coruscate5 对于一周的程序员来说可能没有必要,没有。这个问题并不局限于这样的人。我当然希望看到人们被告知至少在教育过程中的某个时刻不要使用这些“暂停”技巧。我无法充分强调它们不仅不适合给定的任务,而且选择它们来完成此任务掩盖了对单一职责/抽象概念的误解,这是任何开发人员都必须克服的基本缺陷才能开发出高质量的软件。 (3认同)
  • _(续)_ 这是“我的车无法启动;我通过安装帆来修复它”的方法。这是一种必须克服和/或不被教导的心态。 (2认同)

小智 46

请注意,上面的代码
在Windows 7 上的Code :: Blocks 12.11和Visual Studio 2012 上进行了测试.

为了强制您的程序停止或等待,您有几个选择:


  • sleep(unsigned int)

该值必须是以毫秒为单位的正整数.这意味着如果您希望程序等待2秒,请输入2000.

这是一个例子:

#include <iostream>     //for using cout
#include <stdlib.h>     //for using the function sleep

using namespace std;    //for using cout

int main(void)         
{
   cout << "test" << endl;
   sleep(5000);         //make the programme waiting for 5 seconds
   cout << "test" << endl;
   sleep(2000);         // wait for 2 seconds before closing

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果等待时间过长,这可能意味着参数以秒为单位.所以改成它:

sleep(5);
Run Code Online (Sandbox Code Playgroud)

对于那些使用sleep获取错误消息或问题的人,请尝试使用_sleep或Sleep替换它,特别是在Code :: Bloks上.
如果您仍然遇到问题,请尝试在代码的开头添加一个此库.

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <dos.h>
#include <windows.h>
Run Code Online (Sandbox Code Playgroud)
  • 系统("暂停")

Windows控制台应用程序上的一个简单的"Hello world"程序可能会在您看到任何内容之前关闭.那种你可以使用系统的情况("暂停").

#include <iostream>    

using namespace std;   

int main(void)         
{
    cout << "Hello world!" << endl;

    system("PAUSE");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果您收到消息"错误:'系统'未在此范围内声明",只需在代码的大角度添加以下行:

#include <cstdlib>
Run Code Online (Sandbox Code Playgroud)
  • cin.ignore()

使用cin.ignore()可以达到相同的结果:

#include <iostream>     

using namespace std;    

int main(void)         
{
    cout << "Hello world!" << endl;

    cin.ignore();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)
  • cin.get()

例如:

#include <iostream>     

using namespace std;    

int main(void)         
{
    cout << "Hello world!" << endl;

    cin.get();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)
  • 残培()

只是不要忘记添加库conio.h:

#include <iostream>     
#include <conio.h>    //for using the function getch()

using namespace std;    

int main(void)
{

    cout << "Hello world!" << endl;

    getch();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

您可以让消息告诉您使用getch的_getch()

  • 但是**请*不要*这样做**!! 这是一个_massive_抽象泄漏,完全破坏了程序的可链接性.学会正确操作命令行环境.例如`cmd/K myprogram.exe` (5认同)
  • 只是添加,睡眠是针对Linux而睡眠(注意大写)是针对Windows的. (4认同)

dmc*_*kee 20

用于显示文本的窗口的出现和消失是您运行程序的一个特性,而不是C++的特性.

在持久命令行环境中运行,或程序中包含窗口支持,或者使用sleep或等待输入,如其他答案所示.

  • 为什么这不是大规模和最高级的赞成 :( (2认同)
  • 呃...大概是因为大多数人来这个问题都在寻找一种方法来"让它停止这样做!"*而不是讨论它为什么会发生.也许这有点悲伤,用哲学的方式,但那是你的问答. (2认同)

Sin*_*ion 13

相当于批处理程序

#include<iostream>
int main()
{
    std::cout<<"Hello, World!\n";
    std::cin.get();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

附加行正是PAUSE如此,等待单个字符输入

  • 但是**请*不要*这样做**!! 这是一个_massive_抽象泄漏,完全破坏了程序的可链接性.学会正确操作命令行环境.例如`cmd/K myprogram.exe` (4认同)

rr-*_*rr- 7

实际上,与其他答案相反,我认为OP的解决方案是最优雅的解决方案.

以下是使用外部.bat包装器获得的结果:

  1. 应用程序显然等待用户输入,因此它已经做了你想要的.
  2. 你不要用尴尬的电话混乱代码.谁应该等?main()
  3. 您不需要处理跨平台问题 - 请参阅system("pause")此处有多少人建议.
  4. 如果没有这个,要在黑盒测试模型中以自动方式测试你的可执行文件,你需要模拟enter按键(除非你做脚注中提到的事情).
  5. 也许最重要的是-如果任何用户想要通过终端(可以运行应用程序cmd.exe在Windows平台上),他们希望等待,因为他们会看到反正输出.使用.bat包装器技术,他们可以决定是运行.bat(或.sh)包装器,还是直接运行可执行文件.

关注最后两点 - 使用任何其他技术,我希望程序至少提供--no-wait切换,以便我作为用户可以使用应用程序进行各种操作,例如管道输出,将其链接到其他程序等等.这些都是普通CLI工作流程的一部分,当你已经进入终端时,在最后添加等待只会妨碍用户体验.

出于这些原因,IMO .bat解决方案在这里是最好的.


Kev*_*vin 6

有一种C++ 11的方法.这很简单,我相信它是便携式的.当然,正如Orbit中的Lightness Races指出的那样,为了能够在终端中看到Hello World,你不应该这样做,但是有一些很好的理由使用等待函数.无需再费周折,

#include <chrono> // std::chrono::microseconds
#include <thread> // std::this_thread::sleep_for
std::this_thread::sleep_for(std::chrono::microseconds{});
Run Code Online (Sandbox Code Playgroud)

更多细节可在此处获得.另请参见sleep_until.