getch
関数とgetchar
関数の正確な違いは何ですか?
getchar()
は、標準入力から文字を取得する標準関数です。
getch()
は非標準です。キーボードから文字を取得し(標準入力とは異なる場合があります)、エコーしません。
標準C関数はgetchar()
であり、_<stdio.h>
_で宣言されています。それは基本的には時間の夜明け以来存在しています。標準入力(stdin
)から1文字を読み取ります。これは、リダイレクトされていない限り(通常、シェル入力リダイレクト文字_<
_またはパイプを介して)、ユーザーのキーボードです。
getch()
およびgetche()
は、古いMS-DOS関数であり、_<conio.h>
_で宣言されており、Windowsシステムで現在も人気があります。これらは標準C関数ではありません。すべてのシステムに存在するわけではありません。 getch
は、ユーザーがReturnキーを押すのを待つことなく、またキーストロークをエコーすることなく、キーボードから1つのキーストロークをすぐに読み取ります。 getche
は同じですが、doesエコーします。私の知る限り、getch
およびgetche
alwaysはキーボードから読みます。入力リダイレクトの影響を受けません。
getchar
が標準関数である場合、問題が自然に発生します。それを使用して、Returnキーを待たずに、またはエコーせずに1文字を読み取るにはどうすればよいですか。そして、それらの質問への答えは少なくとも少し複雑です。 (実際、それらは非常に複雑であり、getch
とgetche
の永続的な人気について説明していると思います。
答えは、getchar
はエコーや入力バッファリングなどの詳細を制御できないということです。Cに関する限り、これらは低レベルのシステム依存の問題です。
ただし、getchar
が想定する基本的な入力モデルを理解しておくと役立ちます。紛らわしいことに、通常2つ異なるレベルのバッファリングがあります。
ユーザーがキーボードでキーを入力すると、それらはオペレーティングシステムのターミナルドライバーによって読み取られます。通常、デフォルトのモードでは、ターミナルドライバーは入力と同時にキーストロークをエコーします(これにより、ユーザーは入力内容を確認できます)。通常、そのデフォルトモードでは、ターミナルドライバーはある程度の行編集もサポートしています。たとえば、ユーザーはDeleteキーまたはBackspaceキーを押して、誤って入力した文字を削除できます。行編集をサポートするために、端末ドライバーは通常入力バッファーに文字を収集します。ユーザーがReturnキーを押した場合にのみ、そのバッファーの内容が呼び出し側プログラムで使用できるようになります。 (このレベルのバッファリングは、標準入力が実際にキーボードまたはその他のシリアルデバイスである場合にのみ存在します。標準入力がファイルまたはパイプにリダイレクトされている場合、ターミナルドライバーは有効ではなく、このレベルのバッファリングは適用されません。)
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キーの文字コード。)
getch()
入力を取得するだけで、Enterキーを押しても画面に出力として表示されません。
getchar()
入力を取得し、Enterキーを押すと画面に表示されます。
getchar
は標準Cであり、stdio.hにあります。 stdin
から1文字を読み取ります(ほとんどのシステムでは、標準入力ストリーム=コンソール入力)。ユーザーが文字を入力してEnterキーを押す必要があるため、これはブロッキング呼び出しです。ユーザー入力を画面にエコーします。
getc(stdin)
は、他の入力ストリームにも使用できることを除いて、getchar
と100%同等です。
getch
は非標準であり、通常は古くなったMS DOSヘッダーconio.hにあります。最初のキーストローク後にブロックされないことを除いて、getchar
と同じように機能し、ユーザーがEnterキーを押すことなくプログラムを続行できるようにします。画面に入力をエコーしません。
getche
はgetch
と同じですが、これも非標準ですが、画面に入力をエコーします。