【问题标题】:system("pause"); - Why is it wrong?系统(“暂停”); - 为什么错了?
【发布时间】:2010-11-09 14:41:43
【问题描述】:

这是一个我不太明白的问题:

命令system("pause"); 被教授给新程序员,作为暂停程序并等待键盘输入继续的一种方式。然而,这似乎被许多资深程序员视为不应该在不同程度上做的事情。

有人说很好用。有人说只有当你被锁在房间里并且没有人在看时才能使用它。有人说,如果你使用它,他们会亲自上门杀了你。

我自己是一名新程序员,没有接受过正规的编程培训。我使用它是因为我被教导使用它。我不明白的是,如果它不是可以使用的东西,那为什么要教我使用它?或者,另一方面,它真的没有那么糟糕吗?

你对这个问题有什么看法?

【问题讨论】:

标签: c++


【解决方案1】:

它不受欢迎,因为它是一个特定于平台的 hack,与实际学习编程无关,而是为了绕过 IDE/OS 的一个功能 - 从 Visual Studio 启动的控制台窗口在程序完成执行后关闭,因此新用户看不到他的新程序的输出。

Bodging in System("pause") 运行 Windows 命令行“pause”程序并等待该程序终止,然后再继续执行程序 - 控制台窗口保持打开状态,因此您可以读取输出。

一个更好的想法是在最后放置一个断点并对其进行调试,但这又会出现问题。

【讨论】:

  • Visual Studio 可以在两种模式下运行程序:带或不带调试。在调试模式下运行时,它将在第一个断点处停止。如果您没有定义它,它将运行程序并关闭控制台。因此,如果您希望控制台程序停止,只需设置一个断点,或者更好的是,无需调试即可运行它!这将执行程序并停止控制台。
  • 这不仅是 Visual Studio 的一个功能 - 如果您从 Windows 运行控制台程序(即与加载命令提示符并从那里运行相反),它也会在完成后关闭执行。
  • -1 关于“程序执行完毕后从Visual Studio启动的控制台窗口关闭”,不,仅适用于程序在调试器中运行时。重新“运行Windows命令行“暂停”程序”,不存在(pausecmd.exe中的内部命令)。更好的想法列表也严重缺乏。
  • 我认为这个答案是唯一一个涉及这是一种解决方法的方面。它围绕特定执行环境的行为工作,该环境在您阅读程序输出之前关闭终端窗口。你应该做的是修复那个环境。如果无法做到这一点,请使用此解决方法,可能仅当 IsDebuggerPresent() 返回 true 并正确记录此解决方法(“为什么此代码在这里?”)。
【解决方案2】:

很慢。它取决于平台。这是不安全的。

首先:它的作用。调用“系统”就像在 Windows 命令提示符中输入命令一样。您的应用程序需要进行大量的设置和拆卸才能进行这样的调用——而且开销简直是荒谬的。

如果将一个名为“pause”的程序放入用户的 PATH 中会怎样?只调用 system("pause") 只能保证执行名为 "pause" 的程序(希望你的可执行文件没有名为 "pause"!)

只需编写您自己的使用 _getch 的“Pause()”函数。好的,当然,_getch 也依赖于平台(注意:它在“conio.h”中定义)——但如果你在 Windows 上开发它比system() 好得多,并且它具有相同的效果(尽管你有责任为文本提供 cout 左右)。

基本上:当您可以简单地添加两行代码和一个包含并获得更灵活的机制时,为什么还要引入这么多潜在问题?

【讨论】:

  • 对于抱怨平台依赖的人,建议_getch 确实很奇怪,尤其是当标准 C++ 提供getchar 时。
  • 在计算与人类交互的开销时,我觉得有些讽刺)
  • @Spagpants:也许你不明白从人类那里获取输入与人类中生成图像和声音之间的区别。
  • @Cheersandhth.-Alf - 嗯?当我在 8 年前写这篇文章的时候,我刚刚调试完一个由 'system("pause")' 引起的问题,因为项目的可执行文件名为 "pause",它会进入无限循环。我的观点仍然成立,我不知道你为什么说我错了。
  • @paxdiablo getchar 需要输入,然后按 Enter。 _getch 只需要一个按键,无论它是什么键。要在 linux 上模拟 _getch,您需要 5-6 行代码来更改控制台模式,然后将其更改回默认值。它不一样,它做不同的事情。 getchar 不能替代 _getch。
【解决方案3】:
  • 慢:它必须跳过很多 不必要的 Windows 代码和 一个简单的单独程序 操作
  • 不可移植:依赖于 暂停程序
  • 风格不好: 进行系统调用应该只 在真的必要时完成
  • 更多 键入: System("pause") 更长 比 getchar()

一个简单的 getchar() 就可以了。

【讨论】:

    【解决方案4】:

    使用 system("pause"); 是 Ungood Practice™,因为

    • 这完全不必要
      当您从 Visual Studio 运行程序时,要在最后保持程序的控制台窗口打开,请使用 Ctrl+F5 在不调试的情况下运行它,或者在最后放置一个断点main 的右括号 }。所以,在 Visual Studio 中没有问题。当然,当你从命令行运行它时完全没有问题。

    • 这是有问题且烦人的
      当您从命令行运行程序时。对于交互式执行,您必须在最后按一个键而无济于事。并且用于自动化一些 pause 非常不受欢迎的任务!

    • 它不是便携式的。
      Unix-land 没有标准的pause 命令。

    pause 命令是一个内部cmd.exe 命令,不能被覆盖,正如至少在另一个答案中错误地声称的那样。 IE。这不是安全风险,并且声称 AV 程序将其诊断为此类的声明与覆盖命令的声明一样可疑(毕竟,调用 system 的 C++ 程序可以自行完成命令解释器可以做的所有事情, 和更多)。此外,虽然按照 C++ 编程的通常标准,这种暂停方式效率极低,但在新手程序结束时完全没有关系。

    因此,在此之前的大量答案中的声明是不正确的,这是您不应该在 main 末尾使用 system("pause") 或任何其他等待命令的主要原因, 是上面的第一点:完全没有必要,完全没有任何用处,只是非常愚蠢。

    【讨论】:

    • 有时需要一个 Ungood Practice™ 来进行快速测试......我们称之为“又快又脏”
    【解决方案5】:

    总而言之,当您可以使用像 cin.get() 这样简单的东西时,它必须暂停程序执行并进行系统调用并分配不必要的资源。人们使用 System("PAUSE") 是因为他们希望程序等到他们按回车键才能看到他们的输出。如果您希望程序等待输入,则可以使用内置函数,这些函数也是跨平台且要求不高的。

    this文章中进一步解释。

    【讨论】:

    • 哇,又是你!你住在这里吗?大声笑无论如何,谢谢,我会做一些阅读。同时,您对此事有何看法?
    • 几年前我第一次开始使用 C 时也有同样的问题,我被指给了同一篇文章。我个人使用 getchar()。
    • 哇...我已经有一段时间没有使用 C++ 了,但是是的.. 确实有更好的方法来实现相同的结果
    【解决方案6】:

    您可以从iostream 使用std::cin.get()

    #include <iostream> // std::cout, std::cin
    using namespace std;
    
    int main() {
       do {
         cout << '\n' << "Press the Enter key to continue.";
       } while (cin.get() != '\n');
    
       return 0;
    }
    

    此外,system('pause') 很慢,并且包含一个您可能不需要的文件:stdlib.h。它依赖于平台,实际上调用的是“虚拟”操作系统。

    【讨论】:

    • 在第一年的编程课程中,我被教导使用 System("pause"),但我希望能够在我的 Mac 上运行我的程序,所以我必须了解 cin.get()
    【解决方案7】:

    因为它不可移植。
    pause 命令是一个仅限 windows / dos 的程序,所以你的代码不会在 linux/macOS 上运行。此外,system 通常不被认为是调用另一个程序的好方法——通常最好使用CreateProcessfork 或类似的东西。

    【讨论】:

      【解决方案8】:

      正如其他答案中列出的那样,您可以找到许多避免这种情况的原因。这一切都归结为一个使其余部分变得毫无意义的原因。 System() 函数本质上是不安全/不受信任的,除非必要,否则不应将其引入程序中。

      对于学生作业,这个条件从未满足,因此,如果存在对该方法的调用,我什至会在不运行程序的情况下使作业失败。 (这一点从一开始就明确了。)

      【讨论】:

        【解决方案9】:

        对我来说,在无故退出之前等待通常是没有意义的。完成工作的程序应该结束并将其资源交还给它的创建者。

        一个人也不会在一天的工作后默默地等待在黑暗的角落里,等待有人倾肩而过。

        【讨论】:

        • 这是一个愚蠢的答案。程序“做它的工作”的一部分是向用户显示它的工作结果。因此,在用户通知它他们已经完成它之前,它不应该结束。显示结果后一纳秒从用户屏幕上消失的程序是没有用的。
        • @JBentley:我谈到了显示结果之后的情况,如果有的话。为了显示结果,存在适当的模式,如信号、中断、计时器、终端中的回滚、文件。 system("pause") 本身不显示任何内容。一个不是从命令行调用并且过早关闭的命令行界面程序被错误地调用并且带有错误的选项,并且使用system("pause")来规避错误调用的程序确实不是正确的做法。
        • 我的意思是,想象一下catlessviOpenOfficeMathematicaGNU Octave,如果他们使用system("pause")会怎样?那会很烦人。
        • 是的,那会很烦人,但是现在您专门讨论的是system("pause") 的问题,而您的回答是关于“退出前等待”,这是一个更笼统的概念。您给出的许多示例实际上都是“在退出前等待”,直到用户通知程序他们希望它退出。我同意 system("pause") 不是实现这一目标的好方法,并且有更好的解决方案,但这不是你的回答所说的。
        • @JBentley 哦,绝对的:如果延迟/等待/提示是程序语义的一部分,pause 离开!
        【解决方案10】:
        system("pause");  
        

        是错误的,因为它是 Windows API 的一部分,因此在其他操作系统中不起作用。

        您应该尝试仅使用 C++ 标准库中的对象。更好的解决方案是这样写:

        cin.get();
        return 0;
        

        但是如果你的代码中有其他cins 也会导致问题。因为在每个cin 之后,您将点击一个Enter\n,这是一个空格字符。 cin 忽略此字符并将其留在缓冲区中,但cin.get() 获取此剩余字符。因此程序的控制到达return 0 行,控制台在让您看到结果之前关闭。
        为了解决这个问题,我们编写如下代码:

        cin.ignore();  
        cin.get();  
        return 0;
        

        【讨论】:

        • 这有点误导。 system() 是标准的,并不特定于 MS Windows。但是,pause shell 命令是 DOS 遗产,通常只能在其中找到。
        【解决方案11】:

        这是您不应该使用它的一个原因:如果您将程序传递给另一台计算机,它会激怒大多数在 Windows 上运行的防病毒程序,因为它是一种安全威胁。即使你的程序只包含一个简单的cout &lt;&lt; "hello world\n"; system("pause"); 它占用大量资源,并且程序可以访问 cmd 命令,而杀毒软件将其视为威胁。

        【讨论】:

          【解决方案12】:

          专业人士使用 system("PAUSE");创建程序的一小部分是为了自己调试。如果您使用它在您使用的每个过程之前和之后获取变量的结果,以确保它们正常工作。

          在测试并将其与解决方案的其余部分一起全面展开后,您应该删除这些行。在测试用户定义的算法并确保您以正确的顺序执行操作以获得所需的结果时,这非常好。

          在您对它进行测试并确保它可以正常工作之后,您绝对不想在应用程序中使用它。但是,它确实允许您跟踪正在发生的所有事情。根本不要将它用于最终用户应用程序。

          【讨论】:

            【解决方案13】:

            这都是风格问题。它对调试很有用,但不应该在程序的最终版本中使用。内存问题真的没关系,因为我确信那些发明系统(“暂停”)的人预计它会被经常使用。从另一个角度来看,无论如何我们在计算机上使用的所有其他内容都会限制计算机的内存,并且它不会像动态内存分配那样构成直接威胁,因此我建议将它用于调试代码,但仅此而已。

            【讨论】:

            • 内存问题真的没关系,因为我敢肯定那些发明系统的人(“暂停”)预计它会被经常使用 真的没有任何意义。没有人“发明”这个,pause 是为在 DOS 批处理程序中使用而设计的,它从来没有打算以这样的方式使用。此外,在任何人疯狂地输入短语system("pause");之前,还有更好的选择。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-12-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多