getch
とgetchar
関数の正確な違いは何ですか?
4 に答える
getchar()
stdinから文字を取得する標準関数です。
getch()
非標準です。キーボードから文字を取得し(stdinとは異なる場合があります)、エコーしません。
標準C関数はgetchar()
、で宣言されてい<stdio.h>
ます。それは基本的に時間の夜明けから存在してきました。標準入力(stdin
)から1文字を読み取ります。これは、リダイレクトされていない限り(たとえば、シェル入力リダイレクト文字<
またはパイプを介して)、通常はユーザーのキーボードです。
getch()
およびgetche()
は古いMS-DOS関数であり、で宣言されており<conio.h>
、Windowsシステムで今でも人気があります。これらは標準のC関数ではありません。すべてのシステムに存在するわけではありません。getch
ユーザーがReturnキーを押すのを待たずに、またキーストロークをエコーせずに、キーボードから1つのキーストロークをすぐに読み取ります。エコーすることgetche
を除いて、同じです。私の知る限り、そして常にキーボードから読みます。入力リダイレクトの影響を受けません。getch
getche
当然のことながらgetchar
、標準機能の場合、Returnキーを待たずに、またはエコーせずに1文字を読み取るためにどのように使用するのでしょうか。そして、それらの質問への答えは少なくとも少し複雑です。getch
(実際、それらは非常に複雑であるため、との永続的な人気を説明していると思います。getche
これは、他に非常に使いやすいものがない場合でも同様です。)
そしてその答えは、getchar
エコーや入力バッファリングなどの詳細を制御できないということです。Cに関する限り、これらは低レベルのシステム依存の問題です。
ただし、をgetchar
想定した基本的な入力モデルを理解しておくと便利です。紛らわしいことに、通常、2つの異なるレベルのバッファリングがあります。
ユーザーがキーボードでキーを入力すると、オペレーティングシステムのターミナルドライバーによって読み取られます。通常、デフォルトモードでは、ターミナルドライバーは、入力されるとすぐにキーストロークをエコーします(ユーザーは入力内容を確認できます)。通常、デフォルトモードでは、ターミナルドライバはある程度の行編集もサポートしています。たとえば、ユーザーはDeleteキーまたはBackspaceキーを押して、誤って入力した文字を削除できます。行編集をサポートするために、ターミナルドライバは通常、入力バッファに文字を収集します。ユーザーがReturnキーを押した場合にのみ、そのバッファーの内容が呼び出し元のプログラムで使用可能になります。(このレベルのバッファリングは、標準入力が実際にキーボードまたはその他のシリアルデバイスである場合にのみ存在します。標準入力がファイルまたはパイプにリダイレクトされている場合、ターミナルドライバは有効ではなく、このレベルのバッファリングは適用されません。)
stdioパッケージは、オペレーティングシステムから独自の入力バッファに文字を読み取ります。
getchar
そのバッファから次の文字をフェッチするだけです。バッファが空の場合、stdioパッケージは、オペレーティングシステムからさらに文字を読み取ることにより、バッファを補充しようとします。
したがって、プログラムがgetchar
初めて呼び出したときに何が起こるかを追跡すると、stdioは入力バッファが空であることを検出したため、オペレーティングシステムからいくつかの文字を読み取ろうとしますが、まだ使用可能な文字がないため、read
呼び出しブロック。その間、ユーザーはターミナルドライバーの入力バッファーに蓄積されているいくつかの文字を入力している可能性がありますが、ユーザーはまだReturnキーを押していません。最後に、ユーザーがReturnキーを押すと、ブロックされたread
呼び出しが戻り、行全体に相当する文字がにstdio
返されます。これにより、入力バッファーがいっぱいになり、最初の呼び出しが最初の呼び出しに返されますgetchar
。この間ずっと待っています。(そして、プログラムが2回目または3回目の呼び出しを行うgetchar
場合、おそらくさらにいくつかの文字(ユーザーが入力した行の次の文字)は、stdioの入力バッファーでgetchar
すぐに返されるように使用できます。これについてもう少し詳しくは、これらのCコースノートのセクション6.2を参照してください。)
しかし、ご覧のとおり、これらすべてにおいてgetchar
、stdioパッケージは、エコーや入力行の編集などの詳細を制御できません。これらは、ステップ1のターミナルドライバーで、より低いレベルで以前に処理されるためです。
したがって、少なくともUnixライクなオペレーティングシステムでは、Returnキーを待たずに文字を読み取りたい場合、または文字がエコーされるかどうかを制御したい場合は、ターミナルドライバの動作を調整することによってそれを行います。詳細はさまざまですが、エコーのオンとオフを切り替える方法と、入力行の編集のオンとオフを切り替える方法(実際にはいくつかの方法)があります。(これらの詳細の少なくとも一部については、このSOの質問、または古いC FAQリストの質問19.1を参照してください。)
入力行の編集をオフにすると、オペレーティングシステムは(Returnキーを待たずに)すぐに文字を返すことができます。その場合、ユーザーが間違ったキーストロークを入力した可能性があることを心配する必要がないためです。 DeleteキーまたはBackspaceキーを使用して「戻る」。(しかし、同じように、プログラムがターミナルドライバーの入力行編集をオフにした場合、ユーザーに間違いを訂正させたい場合は、独自の編集を実装する必要があります。これは、連続して表示されるためです。を呼び出すと、ユーザーの間違った文字と、DeleteキーまたはBackspaceキーの文字コードgetchar
の両方が返されます。)
getch()
入力を取得するだけですが、Enterキーを押しても、それを出力として画面に表示することはありません。
getchar()
入力を取得し、Enterキーを押すと画面に表示されます。
getchar
stdio.hにある標準Cです。stdin
(標準の入力ストリーム=ほとんどのシステムのコンソール入力)から1文字を読み取ります。ユーザーが文字を入力してEnterキーを押す必要があるため、これはブロッキング呼び出しです。ユーザー入力を画面にエコーします。getc(stdin)
getchar
他の入力ストリームにも使用できることを除いて、は100%同等です。getch
は非標準であり、通常、古い廃止されたMSDOSヘッダーconio.hにあります。最初のキーストローク後にブロックされないことを除いて、同じように機能getchar
し、ユーザーがEnterキーを押さなくてもプログラムを続行できます。画面への入力はエコーされません。getche
と同じですがgetch
、これも非標準ですが、画面への入力をエコーします。