システム(「一時停止」); -なぜそれが間違っているのですか?


131

よくわからない質問があります。

コマンドsystem("pause");は、プログラムを一時停止し、キーボード入力が続くのを待つ方法として、新しいプログラマーに教えられます。ただし、さまざまな程度で行うべきではないものとして、多くのベテランプログラマーによって眉をひそめているようです。

一部の人々はそれを使用するのは結構ですと言います。部屋に閉じ込められていて、誰も見ていないときにのみ使用するためのものだと言う人もいます。彼らが個人的にあなたの家に来てあなたがそれを使うならあなたを殺すと言う人もいます。

私自身、正式なプログラミングトレーニングを受けていない新しいプログラマーです。使うように教えられたので使っています。私が理解していないことは、それが使用されるものではない場合、なぜそれを使用するように教えられたのですか?あるいは、裏返して言えば、結局それほど悪くはないのでしょうか?

この問題についてどう思いますか?



5
どうやら人々は一時停止の呼び出しが本当に効率的であることを好むようです。つまり、「急いで止まって!」ということです。
Lee Louviere、2011

63
一般的に教師が悪いプログラマーですので、あなたはそれを教えられた
ウィッヒ

良い質問をすることについてのこのアドバイスを読んでください:[尋ねる方法 ]、[完璧な質問を書く ]。
Adi Inbar 2014年

9
@wich完全にナンセンス。
Michael Chourdakis、2015年

回答:


85

これは、実際にプログラミングを学習することとは関係なく、代わりにIDE / OSの機能を回避するためのプラットフォーム固有のハックであるため、眉をひそめています。VisualStudioから起動されたコンソールウィンドウは、プログラムの実行が完了すると閉じます。新しいユーザーは彼の新しいプログラムの出力を見ることはできません。

System( "pause")でのボーディングは、Windowsコマンドラインの "pause"プログラムを実行し、プログラムの実行を続行する前に終了するのを待ちます-コンソールウィンドウは開いたままなので、出力を読むことができます。

より良いアイデアは、最後にブレークポイントを置いてデバッグすることですが、これにも問題があります。


6
Visual Studioは、プログラムを2つのモードで実行できます。デバッグありまたはデバッグなしです。デバッグモードで実行すると、最初のブレークポイントで停止します。定義されていない場合は、プログラムを実行してコンソールを閉じます。したがって、コンソールプログラムを停止したい場合は、ブレークポイントを設定するか、さらにはデバッグなしで実行してください。プログラムが実行され、コンソールが停止します。
Ivan Mesic 2013

これはVisual Studioの機能だけではありません。Windowsからコンソールプログラムを実行すると(つまり、コマンドプロンプトを読み込んでそこから実行するのではなく)、実行が終了すると終了します。
JBentley 2013

2
-1「プログラムが実行を完了するとVisual Studioから起動されたコンソールウィンドウが閉じる」については、いいえ、デバッガーでプログラムが実行されたときのみです。再度「Windowsコマンドラインの「一時停止」プログラムを実行します」、そのようなものはありません(pauseの内部コマンドですcmd.exe)。優れたアイデアのリストも大幅に不足しています。
乾杯とhth。-Alf

この回答は、これが回避策であるという側面に触れる唯一の回答だと思います。プログラムの出力を読み取る前にターミナルウィンドウを閉じる特定の実行環境の動作を回避します。あなたがすべきことは、その環境を修正することです。それができない場合は、この回避策を使用してくださいIsDebuggerPresent()。trueが返された場合にのみ、この回避策を適切に文書化してください(「このコードはなぜここにあるのですか?」)。
Ulrich Eckhardt

43

遅いです。プラットフォームに依存します。それは安全ではありません。

最初:それが何をするか。「システム」の呼び出しは、文字通り、Windowsコマンドプロンプトにコマンドを入力するのと同じです。アプリケーションがそのような呼び出しを行うには、セットアップとティアダウンが大量にあり、オーバーヘッドはばかげています。

「一時停止」というプログラムがユーザーのPATHに置かれた場合はどうなりますか?system( "pause")を呼び出すだけで、 "pause"というプログラムが実行されることが保証されるだけです( "pause"という名前の実行可能ファイルがないことを期待してください)。

_getchを使用する独自の "Pause()"関数を記述するだけです。確かに、_getchもプラットフォームに依存します(注: "conio.h"で定義されています)-しかしsystem()、Windowsで開発している場合よりもはるかに優れており、同じ効果があります(テキストを提供するのはユーザーの責任です) cout程度)。

基本的に:単純に2行のコードと1行のインクルードを追加して、はるかに柔軟なメカニズムを取得できるのに、なぜ多くの潜在的な問題が発生するのでしょうか。


61
プラットフォームの依存について不平を言う人にとって_getch特に標準のC ++が提供してgetcharいる場合は、提案するのは確かに奇妙に思えます。
paxdiablo 2012年

33
私は人間とのやり取りのオーバーヘッドを計算するときにいくらか皮肉を感じます)
ShPavel

1
@Spagpants:人間から入力を取得することと、人間で画像や音声生成することの違いを理解していない可能性があります。
yzt 2015

1
@ Cheersandhth.-Alf-うーん?8年前にこれを書いたとき、プロジェクトの実行可能ファイル名が「一時停止」と呼ばれ、無限ループになるため、「system( "pause")」によって引き起こされた問題のデバッグを終えたところです。私の主張はまだ残っています、なぜあなたが私が間違っていたと言っているのかわかりません。

2
@paxdiablo getcharには入力が必要で、Enterキーを押します。_getchは、どのキーであってもキーを押すだけで済みます。Linuxで_getchをエミュレートするには、5〜6行のコードでコンソールモードを変更し、それをデフォルトに戻す必要があります。同じではなく、違うことをします。getcharは_getchの代わりにはなりません。
Barnack

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
アンクイックプラクティス™がクイックテストに必要な場合があります。「クイックアンドダーティー」と呼ばれるもの
Michael Haephrati 2018年

22

要約すると、cin.get()のような単純なものを使用できる場合は、プログラムの実行を一時停止し、システムコールを実行して不要なリソースを割り当てる必要があります。人々は彼らが彼らの出力を見ることができるようにエンターを打つまで彼らがプログラムを待たせたいのでSystem( "PAUSE")を使います。プログラムが入力を待つようにしたい場合は、クロスプラットフォームで要求の少ない関数が組み込まれています。

この記事での詳細な説明。


わあ、また!ここに住んでるの?笑とにかく、おかげで、私はいくつかの読書をします。それまでの間、この件に関するあなたの考えを教えてください。
Faken、2009

数年前にCを始めたときも同じ質問があり、同じ記事を指摘されました。私は個人的にgetchar()を使用しています。
ジョンT

うわぁ...私はしばらくC ++を使用していませんが、そうです。同じ結果を達成するための決定的に優れた方法があります
Newtopian

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。これはプラットフォームに依存し、実際には「仮想」OSを呼び出します。


3
System("pause")初年度のプログラミングコースで使用するように教えられましたが、自分のMacでプログラムを実行できるようにしたかったので、について学ぶ必要がありましたcin.get()
daviewales 2014年

10

ポータブルではないからです。

pause

Windows / dosのみのプログラムなので、このコードはLinuxでは実行できません。また、system一般的に他のプログラムを呼び出すための非常に良い方法と見なされていない-それは通常より良く使っているCreateProcessか、forkまたは類似した何か。


4

他の回答に記載されているように、これを回避するために見つけることができる多くの理由があります。それはすべて、残りの部分を不愉快にする1つの理由に要約されます。System()関数は、本質的に安全/信頼され、必要な場合を除きプログラムに導入すべきではありません。

学生の課題の場合、この条件は満たされなかったため、このメソッドの呼び出しが存在する場合、プログラムを実行しなくても課題に失敗しました。(これは最初から明らかにされました。)


4

私にとって、理由もなく終了する前に待つことは、一般的に意味がありません。作業を終えたプログラムは終了し、そのリソースを作成者に戻します。

また、1日の仕事が終わった後、暗いコーナーで黙って待つのではなく、誰かが肩を傾けるのを待ちます。


7
これはばかげた答えです。「その作業を行う」プログラムの一部は、その作業の結果をユーザーに表示しています。したがって、ユーザーが終了したことをユーザーが通知するまで、終了しないでください。結果を表示してからナノ秒後にユーザーの画面から消えるプログラムは役に立たない。
JBentley 2013

1
@JBentley:もしあれば、結果を表示したの状況について話しました。結果を表示するために、信号、割り込み、タイマー、端末のスクロールバック、ファイルなどの適切なパターンが存在します。system("pause")それ自体は何も表示しません。コマンドラインからではなく、早く終了するコマンドラインインターフェースプログラムが誤って、間違ったオプションでsystem("pause")呼び出されます。誤って呼び出されたプログラムを回避するために使用することは、実際には適切なことではありません。
セバスチャンマッハ

1
私は想像する、意味catlessviOpenOfficeMathematicaGNU Octave、彼らは何を使用したい場合はsystem("pause")?それは煩わしいでしょう。
セバスチャンマッハ

2
はい、それは厄介ですが、今は具体的にの問題について話しているのsystem("pause")に対し、答えははるかに一般化された概念である「終了する前に待つ」について話します。提供した例の多くは、ユーザーがプログラムに終了することを通知するまで、実際には「終了する前に待機」します。それsystem("pause")はそれを達成する良い方法ではなく、より良い解決策があることには同意しますが、それはあなたの答えが言うことではありません。
JBentley 2013

1
@JBentleyああ、絶対:遅延/待機/プロンプトがプログラムのセマンティクスの一部である場合、pause離れて!
オービット

3
system("pause");  

これはWindows APIの一部であり、他のオペレーティングシステムでは機能しないため、誤りです。

C ++標準ライブラリのオブジェクトのみを使用するようにしてください。より良い解決策は次のようにすることです:

cin.get();
return 0;

ただしcin、コードに他のが含まれている場合にも問題が発生します。それぞれの後にcin、空白文字であるEnteror \nをタップするからです。cinこの文字を無視してバッファゾーンに残しますがcin.get()、この残りの文字を取得します。そのため、プログラムの制御が限界に達しreturn 0、結果が表示される前にコンソールが閉じられます。
これを解決するには、次のようにコードを記述します。

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

それは少し誤解を招きやすいです。system()標準であり、MS Windowsに固有ではありません。ただし、pauseシェルコマンドはDOSの遺産であり、通常はそこにしかありません。
Ulrich Eckhardt

1

これを使用してはいけない理由の1つは、セキュリティの脅威であるため、プログラムを別のマシンに渡すと、Windowsで実行されているほとんどのウイルス対策プログラムを怒らせることになります。あなたのプログラムが単純なcout << "hello world\n"; system("pause"); それだけで構成されている場合でも、リソースは重いため、プログラムはcmdコマンドにアクセスできます。これは、アンチウイルスが脅威と見なします。


-1

プロがsystem( "PAUSE");を使用する プログラムの小さな部分を作成するのは、自分でデバッグするためです。変数の結果を取得するためにそれを使用する場合は、各プロセスの前後の間に、それらが正しく機能していることを確認するために使用しています。

それをテストし、残りのソリューションで本格的に動かした後、これらの行を削除する必要があります。ユーザー定義のアルゴリズムをテストして、必要な結果を得るために適切な順序で処理を実行していることを確認する場合は、非常に便利です。

テストして適切に機能していることを確認した後で、これをアプリケーションで使用することは決してありません。しかし、それはあなたがそれが起こっているときに起こっているすべてのものを追跡することを可能にします。エンドユーザーアプリには使用しないでください。


-3

それはすべてスタイルの問題です。これはデバッグに役立ちますが、それ以外の場合は、プログラムの最終バージョンでは使用しないでください。システムを発明した人たち( "一時停止")がシステムが頻繁に使用されることを予想していたので、メモリの問題は本当に重要ではありません。別の見方をすると、コンピューターは、私たちがコンピューターで使用する他のすべてのものについて、メモリを抑制し、動的メモリ割り当てなどの直接的な脅威をもたらすことはないので、コードのデバッグだけに推奨します。


6
システムを発明した人たち(「一時停止」)がシステムの使用を予測していたため、メモリの問題は実際には問題になりません。pause誰もがこれを「発明」したものではなく、DOSバッチプログラムで使用するために設計されたもので、このような方法で使用することは決して意図されていません。さらに、フレーズを入力するのに夢中になる前に、はるかに優れた選択肢がありましたsystem("pause");
ウィッヒ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.