系统(“暂停”);-为什么错了?


131

这是我不太了解的问题:

system("pause");向新程序员讲授该命令,作为暂停程序并等待键盘输入继续的一种方式。但是,许多资深程序员似乎不赞成这样做,因为这不应在不同程度上进行。

有人说可以使用。有人说,仅当您被锁在房间内且没人在看的时候才使用它。有人说,如果您使用它们,他们会亲自来到您家杀死您。

我本人是一名新程序员,没有经过正式的编程培训。我使用它是因为我被教导要使用它。我不明白的是,如果不使用它,为什么要教我使用它?或者,从另一方面来说,这真的不是那么糟糕吗?

您对此主题有何看法?



5
显然,人们喜欢暂停通话以提高效率。换句话说,“快点停下来!”
Lee Louviere

63
你被教导,因为通常老师是坏的程序员
至极

请阅读有关以下常见问题的建议:[ 如何提问 ],[提出完美的问题 ]。
Adi Inbar 2014年

9
@wich完全是胡说八道。
Michael Chourdakis

Answers:


85

人们之所以对此表示反对,是因为它是一个特定于平台的黑客,与实际学习编程无关,而是为了避开IDE / OS的功能-从Visual Studio启动的控制台窗口在程序完成执行后关闭,因此新用户看不到新程序的输出。

在System(“ pause”)中进行绑定将运行Windows命令行“ pause”程序,并等待该终止终止,然后继续执行该程序-控制台窗口保持打开状态,以便您读取输出。

一个更好的主意是将一个断点放在最后并对其进行调试,但这又有问题。


6
Visual Studio可以以两种模式运行该程序:有或没有调试。在调试模式下运行时,它将在第一个断点处停止。如果没有定义,它将运行程序并关闭控制台。因此,如果要停止控制台程序,只需设置一个断点,或者甚至更好地运行它而无需调试!这将执行程序并停止控制台。
伊万·梅西奇

这不仅是Visual Studio的功能-如果您从Windows运行控制台程序(即,与加载命令提示符并从那里运行相反),则它在完成执行后也会关闭。
JBentley 2013年

2
−1否“仅当在调试器中运行程序时,才关闭从Visual Studio启动的控制台窗口”,否。重新“运行Windows命令行“暂停”程序”,没有不存在这样pause的命令(是内部命令cmd.exe)。也严重缺乏更好的主意清单。
干杯和健康。-Alf

我认为这个答案是唯一可以解决此问题的方法。它可以解决特定执行环境的行为,该环境会在您读取程序输出之前关闭终端窗口。您应该做的就是修复该环境。如果无法做到这一点,请使用此替代方法,仅当IsDebuggerPresent()返回true并正确记录此替代方法时才使用(“为什么在此输入代码?”)。
Ulrich Eckhardt

43

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

第一:它做什么。从字面上看,调用“系统”就像在Windows命令提示符下键入命令。您的应用程序需要进行大量的设置和拆卸才能发出这样的调用-开销简直是荒谬的。

如果将名为“暂停”的程序放入用户的PATH,该怎么办?仅调用system(“ pause”)仅可确保执行名为“ pause”的程序(希望您没有名为“ pause”的可执行文件!)

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

基本上:为什么只需添加两行代码,其中一个包含,并获得更加灵活的机制,为什么会引入这么多潜在的问题?


61
对于抱怨平台依赖性的人来说,提出建议似乎有些奇怪_getch尤其是当标准C ++提供时getchar
paxdiablo 2012年

33
我在计算与人互动的开销时有些讽刺意味)
ShPavel

1
@Spagpants:也许你不明白的人得到信息,并生成图像和声音之间的差别人。
yzt 2015年

1
@Cheersandhth。-Alf-嗯?8年前,当我写这篇文章时,我刚刚调试完了一个由'system(“ pause”)'引起的问题,因为该项目的可执行文件名为“ pause”,并且会陷入无限循环。我的观点仍然存在,我不确定你为什么要说我不正确。

2
@paxdiablo getchar需要输入,然后按Enter。_getch只需按下一个按键,无论它是什么按键。要在Linux上模拟_getch,您需要5-6行代码来更改控制台模式,然后将其更改回默认值。不一样,它做不同的事情。getchar不能替代_getch。
巴纳克

29
  • 速度慢:它必须跳过许多不必要的Windows代码和单独的程序才能进行简单的操作
  • 不可移植:取决于暂停程序
  • 不好的风格:仅在确实必要时才进行系统调用
  • 输入更多:System(“ pause”)比getchar()长

一个简单的getchar()应该可以。


26

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

  • 完全没有必要
    当您从Visual Studio运行该程序时,若要在最后打开该程序的控制台窗口,请使用Ctrl+F5无需调试运行,否则发生在最后的右括号断点}main。因此,在Visual Studio中没有问题。当然,从命令行运行它完全没有问题。

  • 有问题又烦人
    当您从命令行运行程序时,。对于交互式执行,您无须在最后按任何键。并用于某些pause非常不希望的任务的自动化中!

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

pause命令是一个内部cmd.exe命令,不能被覆盖,正如至少一个其他答案中错误地指出的那样。也就是说,这不是安全隐患,并且AV程序可以这样诊断它的说法与覆盖命令的声明一样具有可疑性(毕竟,C ++程序调用system可以自行执行命令解释器可以做的所有事情,并且更多)。同样,尽管这种暂停方式在C ++编程的通常标准下效率极低,但是这对新手程序结束时根本没有关系。

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


1
有时,需要使用Ungood Practice™来进行快速测试。...我们所谓的“快速又肮脏”
Michael Haephrati

22

总之,当您使用诸如cin.get()之类的简单内容时,它必须暂停程序执行,进行系统调用并分配不必要的资源。人们之所以使用System(“ PAUSE”),是因为他们希望程序等待,直到按下回车键才能看到其输出。如果要让程序等待输入,则有内置的函数,这些函数也跨平台且要求较低。

在进一步的解释文章。


哇,你又来了!你住在这里吗?大声笑无论如何,谢谢,我会读书。同时,您对此事有何看法?
Faken

几年前刚开始使用C时,我也遇到了同样的问题,当时我也被指向同一篇文章。我个人使用getchar()。
约翰T

哇...我已经有一段时间没有做C ++了,是的..绝对有更好的方法可以达到相同的效果
Newtopian 2009年

16

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

#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。它依赖于平台,实际上调用了一个“虚拟”操作系统。


3
我被教导要System("pause")在第一年的编程课程中使用它,但是我希望能够在Mac上运行我的程序,因此我必须学习cin.get()
daviewales 2014年

10

因为它不是便携式的。

pause

是Windows / Dos Only程序,因此此代码不会在Linux上运行。而且,system通常不被认为是调用另一个程序的一种很好的方法-通常最好使用CreateProcessfork类似的东西。


4

正如其他答案中列出的那样,有很多原因可以避免这种情况。一切归结为使其余问题无聊的一个原因。该System()功能本质上是不安全/不受信任的,除非有必要,否则不应将其引入程序中。

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


4

对我而言,通常无故退出之前等待是没有意义的。一个已经完成工作的程序应该只是结束并将其资源移交给其创建者。

一个工作日后,一个人也不会默默地在黑暗的角落里等待,等待某人向小费。


7
这是一个愚蠢的答案。程序“执行其工作”的一部分正在向用户显示其工作结果。因此,直到用户通知它完成后,它才应该结束。在显示结果后一纳秒内消失在用户屏幕上的程序是没有用的。
JBentley 2013年

1
@JBentley:我谈的情况后,显示结果,如果有的话。为了显示结果,存在适当的模式,例如信号,中断,计时器,终端中的回滚,文件。system("pause")本身不显示任何内容。不是从命令行调用并且关闭得太早的命令行界面程序会错误地使用错误的选项被调用,并且使用system("pause")规避错误调用的程序的确不是正确的选择。
塞巴斯蒂安·马赫2013年

1
我的意思是,试想catlessviOpenOfficeMathematicaGNU Octave,,如果他们想用什么system("pause")?那会很烦人。
塞巴斯蒂安·马赫2013年

2
是的,这很烦人,但是现在您正在专门讨论的问题system("pause"),而您的答案是关于“退出之前先等待”,这是一个更为笼统的概念。实际上,您给出的许多示例都是“等待退出”,直到用户通知程序他们希望退出。我同意这system("pause")不是实现此目标的好方法,并且有更好的解决方案,但这不是您的回答所说的。
JBentley 2013年

1
@JBentley哦,绝对:如果延迟/等待/提示是程序语义的一部分,那就pause走了!
Lightness Races in Orbit

3
system("pause");  

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

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

cin.get();
return 0;

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

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

这有点误导。system()是标准的,并非特定于MS Windows。但是,pauseshell命令是DOS的传统,通常只能在此找到。
Ulrich Eckhardt

1

这是您不应该使用它的原因之一:如果将Windows上运行的大多数防病毒程序传递给另一台计算机,这会惹恼它,因为这是一种安全威胁。即使您的程序仅包含一个简单cout << "hello world\n"; system("pause"); 的资源,也可以访问cmd命令,而反病毒将其视为威胁。


-1

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

经过测试并将其与其余解决方案一起全面展开后,您应该删除这些行。在测试用户定义的算法并确保以正确的顺序进行操作以实现所需结果时,这真的很好。

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


-3

这都是风格问题。它对于调试很有用,但否则不应在程序的最终版本中使用。在内存问题上这并不重要,因为我敢肯定那些发明了该系统(“暂停”)的人正在预料它会经常使用。从另一个角度看,计算机会为我们在计算机上使用的其他所有东西而限制其内存,并且它不会像动态内存分配那样构成直接威胁,因此我建议您将其用于调试代码,但别无其他建议。


6
在内存问题上,这并不重要,因为我敢肯定那些发明了该系统(“暂停”)的人正在预料到它会经常被使用,实际上并没有任何意义。没有人“发明”这个程序,pause是专为在DOS批处理程序中使用而设计的,从来没有打算以这种方式使用它。此外,在有人疯狂地键入该短语之前,有更好的替代方法system("pause");
2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.