在C ++程序中暂停控制台

时间:2014-07-16 08:49:03

标签: c++

哪种方法可以在C ++程序中暂停控制台?

  1. 使用cin.get()
  2. 或使用system("pause")
  3. 或使用getch()getchar()
  4. 等C函数

    使用system("pause")会导致非可移植代码并且无法在UNIX中运行吗?

    cin.get()最好用来暂停控制台吗?

11 个答案:

答案 0 :(得分:59)

可能有一种最好的方法(比如使用便携式cin.get()),,但良好方式不存在。完成工作的程序应该退出并将其资源返回给计算机。

是的,system()的任何使用都会导致不可移植的代码,因为参数会传递给拥有您的进程的shell。

迟早会在源代码中使用暂停代码会导致麻烦:

  • 有人忘记在登记前删除暂停代码
    • 现在所有工作伙伴都不得不怀疑为什么应用程序不再关闭
    • 版本历史被污染
  • #define是地狱
  • 对于从控制台运行代码的任何人来说都很烦人
  • 尝试从脚本中启动和结束程序时非常非常烦人;如果您的程序是shell中管道的一部分,则会产生四倍的烦恼,因为如果程序没有结束,shell脚本或管道也不会,

相反,请探索您的IDE。它可能有一个选项,在运行后不关闭控制台窗口。如果没有,作为一个值得她/他的钱的开发商,你总是在附近打开一个控制台窗口,这是一个很好的理由。

或者,您可以将其设为程序选项,但我个人从未见过带有--keep-alive-when-dead选项的程序。

故事的道德:这是用户的问题,而不是程序的问题。不要污染你的代码。

答案 1 :(得分:16)

如果你想编写可移植的C ++代码,那么我建议使用cin.get()

system("PAUSE")适用于Windows,因为它需要执行名为“PAUSE”的控制台命令。但我不确定Linux或其他Unix衍生产品等其他操作系统是否支持这一点。所以这往往是不便携的。

由于C ++已经提供cin.get(),我认为没有令人信服的理由使用C getch()

答案 2 :(得分:2)

  

哪种方法可以在C ++程序中暂停控制台?

system("pause");getch();(来自DOS世界,IIRC)都是不可移植的。

  

cin.get()最好用来暂停控制台吗?

作为唯一一个便携式标准选项,我会说是,但我个人认为不应该编写交互式控制台程序,即实际暂停的程序控制台或提示输入(除非有真的这样做的理由,因为这会使shell脚本更加困难)。控制台程序应该通过命令行参数与用户交互(或者至少那种交互应该是默认的交互)。

以防你需要暂停程序,我的程序是从IDE启动并立即关闭但我没有足够的时间去看 - 结果的原因 - 不要这样做。只需配置IDE或直接从控制台启动 console 程序。

答案 3 :(得分:2)

最佳方式在很大程度上取决于目标平台,调试与发布使用等。

我认为没有一种最好的方式,但要强迫&#34;强迫&#34;以相当通用的方式等待输入类型场景,特别是在调试时(通常根据NDEBUG_DEBUG编译或编译),您可以尝试std::getline如下< / p>

inline void wait_on_enter()
{
    std::string dummy;
    std::cout << "Enter to continue..." << std::endl;
    std::getline(std::cin, dummy);
}

我们没有&#34;根据需要输入继续&#34;

答案 4 :(得分:2)

没有良好的方法,但您应该使用可移植解决方案,因此请避免system()调用,在您的情况下,您可以使用cin.get()或{{1正如你在问题中提到的那样,也有一个建议。使所有暂停由一个(或极少数)预处理器定义控制。

例如:

全局文件中的某个地方:

getch()

代码中的某处

#define USE_PAUSES
#ifndef _DEBUG    //I asume you have _DEBUG definition for debug and don't have it for release build
#undef USE_PAUSES
#endif

这不是普遍的建议,但你应该保护自己不要在发布版本中放置暂停,这些应该很容易控制,我提到的全局文件可能不那么全球化,因为这可能会导致很长的编译。

答案 5 :(得分:1)

(我的答案部分基于Yoank的答案,部分基于另一个问题的comment Justin Time。)

cout << endl << "Press <Enter> to continue...";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin.get();

答案 6 :(得分:0)

我只是想补充说有一种方法可以获得你想要的东西,但它需要使用一些第三方库(或你自己编写平台相关代码)。

就我而言,cin的最大缺点是你需要点击Return,而不仅仅是任何键。

假设你有一个按键监听器,你可以很容易地编写一个等待用户点击任何键的函数。但是,找到一个独立于平台的关键监听器并非易事,而且很可能需要您加载更大的库的一部分。

我正在思考以下几点:

char wait_for_key() {
    int key;
    while ( ! (key == key_pressed(ANY)) ) {
          this_thread::yield();
    }
    return convert_virtual_key_to_char(key);
}

实际功能显然与我写的完全不同,具体取决于您使用的库。

我知道以下库有keylisteners(如果你知道的话,可以在编辑中添加更多内容。):

答案 7 :(得分:0)

我总是使用几行代码来清除任何字符的输入流,然后等待输入忽略。

类似的东西:

void pause() {
    cin.clear();
    cout << endl << "Press any key to continue...";
    cin.ignore();
}

然后在程序中我需要它时,我有自己的暂停();功能,没有系统暂停的开销。在编写您想要保持打开的控制台程序时,这只是一个问题,或者在某个点上保持注意力。

答案 8 :(得分:0)

这适合我。

void pause()
{
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    std::string dummy;
    std::cout << "Press any key to continue . . .";
    std::getline(std::cin, dummy);
}

答案 9 :(得分:0)

最新的反应,但我认为这会帮助其他人。

模仿系统(“ pause”)的一部分是模仿它要求用户执行的操作:“按任意键继续...。”因此,我们需要一些不等待简单返回的std :: cin .get()可以。甚至getch()在使用两次时也会遇到问题(如果第二次调用在同一次按键后立即再次暂停,则通常会注意到第二次跳过暂停)。我认为这与输入缓冲区有关。通常不建议使用System(“ pause”),但我们仍然需要模仿用户可能已经期望的东西。我更喜欢getch(),因为它不会回显屏幕,并且可以动态工作。

解决方案是使用do-while循环执行以下操作:

void Console::pause()
{ 
    int ch = 0;

    std::cout << "\nPress any key to continue . . . ";

    do {
        ch = getch();
    } while (ch != 0);

    std::cout << std::endl;
} 

现在,它等待用户按任意键。如果两次使用,它将再次等待用户,而不是跳过。

答案 10 :(得分:0)

system("pause") 是在 Windows 中暂停控制台的一种完全有效的方式,“暂停”实际上是 Windows 识别的系统命令,因此,您永远不必担心它会调用同名程序,或类似的东西。 system("pause") 在这方面是危险的想法是神话。

然而在windows之外情况并非如此,因此最好使用预处理器来划分平台。

#ifdef _WIN32 || _WIN64
if(argc <= 1) // optional, prevents pausing if the user runs "program.exe -lol"
    system("pause");
#endif

您可以添加预处理器分支以在其他平台上暂停,只要您认为合适...但在我看来,将它提供给 Windows 就足够了,因为无论如何 Linux 用户更有可能从控制台运行东西。此外,如果您有命令行解析器,则可以使用某些参数关闭暂停。 (你看到的代码片段中的条件实际上是“任何参数”,只是一个懒惰的例子。)