web-dev-qa-db-ja.com

getch()とgetchar()の違いは何ですか?

getch関数とgetchar関数の正確な違いは何ですか?

19
bubble

getchar()は、標準入力から文字を取得する標準関数です。

getch()は非標準です。キーボードから文字を取得し(標準入力とは異なる場合があります)、エコーしません。

28
Roy Dictus

標準C関数はgetchar()であり、_<stdio.h>_で宣言されています。それは基本的には時間の夜明け以来存在しています。標準入力(stdin)から1文字を読み取ります。これは、リダイレクトされていない限り(通常、シェル入力リダイレクト文字_<_またはパイプを介して)、ユーザーのキーボードです。

getch()およびgetche()は、古いMS-DOS関数であり、_<conio.h>_で宣言されており、Windowsシステムで現在も人気があります。これらは標準C関数ではありません。すべてのシステムに存在するわけではありません。 getchは、ユーザーがReturnキーを押すのを待つことなく、またキーストロークをエコーすることなく、キーボードから1つのキーストロークをすぐに読み取ります。 getcheは同じですが、doesエコーします。私の知る限り、getchおよびgetchealwaysはキーボードから読みます。入力リダイレクトの影響を受けません。

getcharが標準関数である場合、問題が自然に発生します。それを使用して、Returnキーを待たずに、またはエコーせずに1文字を読み取るにはどうすればよいですか。そして、それらの質問への答えは少なくとも少し複雑です。 (実際、それらは非常に複雑であり、getchgetcheの永続的な人気について説明していると思います。

答えは、getcharはエコーや入力バッファリングなどの詳細を制御できないということです。Cに関する限り、これらは低レベルのシステム依存の問題です。

ただし、getcharが想定する基本的な入力モデルを理解しておくと役立ちます。紛らわしいことに、通常2つ異なるレベルのバッファリングがあります。

  1. ユーザーがキーボードでキーを入力すると、それらはオペレーティングシステムのターミナルドライバーによって読み取られます。通常、デフォルトのモードでは、ターミナルドライバーは入力と同時にキーストロークをエコーし​​ます(これにより、ユーザーは入力内容を確認できます)。通常、そのデフォルトモードでは、ターミナルドライバーはある程度の行編集もサポートしています。たとえば、ユーザーはDeleteキーまたはBackspaceキーを押して、誤って入力した文字を削除できます。行編集をサポートするために、端末ドライバーは通常入力バッファーに文字を収集します。ユーザーがReturnキーを押した場合にのみ、そのバッファーの内容が呼び出し側プログラムで使用できるようになります。 (このレベルのバッファリングは、標準入力が実際にキーボードまたはその他のシリアルデバイスである場合にのみ存在します。標準入力がファイルまたはパイプにリダイレクトされている場合、ターミナルドライバーは有効ではなく、このレベルのバッファリングは適用されません。)

  2. Stdioパッケージは、オペレーティングシステムから独自の入力バッファーに文字を読み取ります。 getcharは、単にそのバッファから次の文字をフェッチします。バッファーが空の場合、stdioパッケージは、オペレーティングシステムからさらに文字を読み取って、バッファーを補充しようとします。

したがって、プログラムが最初にgetcharを呼び出したときに何が起こるかを追跡すると、stdioは入力バッファーが空であることを検出し、オペレーティングシステムからいくつかの文字を読み取ろうとしますが、何もありません。文字はまだ使用できるため、read呼び出しはブロックします。その間、ユーザーは一部の文字を入力している可能性がありますが、それらはターミナルドライバーの入力バッファーに蓄積されますが、まだReturnキーを押していません。最後に、ユーザーがReturnキーを押すと、ブロックされたread呼び出しが返され、1行分の文字がstdioに返されます。これにより、これらの文字を使用して入力バッファーが満たされ、そこから最初のgetcharへの最初の呼び出しは、これまでずっと根気よく待っていました。 (そして、プログラムがgetcharを2回または3回呼び出す場合、おそらくareいくつかの文字があります-次の文字ユーザーが入力した行-getcharがstdioの入力バッファーですぐに戻るために使用できます。これについての詳細は、 セクション6.2 これらの Cコースノート を参照してください=。)

しかし、これらすべてについて、ご覧のとおり、getcharとstdioパッケージは、エコーや入力行編集などの詳細を制御できません。ステップ1。

したがって、少なくともUnixライクなオペレーティングシステムでは、Returnキーを待たずに文字を読み取ったり、文字をエコーするかどうかを制御したりする場合は、ターミナルドライバの動作を調整することで行います。詳細は異なりますが、エコーをオンまたはオフにする方法と、入力行編集をオンまたはオフにする方法(実際にはいくつかの方法)があります。 (これらの詳細の少なくとも一部については、 this SO question 、または以前の question 19.1 を参照してください C FAQリスト 。)

入力行の編集がオフになっている場合、オペレーティングシステムは(Returnキーを待たずに)すぐに文字を返すことができます。その場合、ユーザーが「実行」する必要がある間違ったキーストロークを入力した可能性があるため、心配する必要はありません。 DeleteキーまたはBackspaceキーで「戻る」。 (しかし、同じように、プログラムがターミナルドライバーで入力行の編集をオフにした場合、ユーザーが間違いを修正できるようにするには、独自の編集を実装する必要があります。 getcharの呼び出しが返されます-ユーザーの間違った文字の両方がDeleteまたはBackspaceキーの文字コード。)

3
Steve Summit

getch()入力を取得するだけで、Enterキーを押しても画面に出力として表示されません。

getchar()入力を取得し、Enterキーを押すと画面に表示されます。

1
funny
  • getcharは標準Cであり、stdio.hにあります。 stdinから1文字を読み取ります(ほとんどのシステムでは、標準入力ストリーム=コンソール入力)。ユーザーが文字を入力してEnterキーを押す必要があるため、これはブロッキング呼び出しです。ユーザー入力を画面にエコーします。

  • getc(stdin)は、他の入力ストリームにも使用できることを除いて、getcharと100%同等です。

  • getchは非標準であり、通常は古くなったMS DOSヘッダーconio.hにあります。最初のキーストローク後にブロックされないことを除いて、getcharと同じように機能し、ユーザーがEnterキーを押すことなくプログラムを続行できるようにします。画面に入力をエコーし​​ません。

  • getchegetchと同じですが、これも非標準ですが、画面に入力をエコーし​​ます。

0
Lundin