2017-02-14 30 views
7

これはKernighanとRitchieの18ページから来ている非常に基本的なCの質問です。getchar()がバックスペースなどの文字を読み取っていないのはなぜですか?

私は、キーボードからの文字入力をカウントするため、この非常に簡単なコードをコンパイルした:

#include <stdio.h> 

/* count characters in input; 1st version */ 
main() 
{ 
    long nc; 

    nc = 0; 
    while (getchar() != EOF) 
    ++nc; 
    printf("%1d\n", nc); 
} 

これは罰金コンパイル、それは、正常に動作し、すなわち予想通り、私は「Hello Worldの」と入力すると、かなりの振る舞いCTRLDを押してEOF文字を入力すると、値11が返されます。

私が間違っていると、バックスペースを使用して文字を削除して再入力することができ、EOFを呼び出すときに端末が表示する文字数だけが返されます。

4文字を入力すると2文字を削除し、別の2文字を入力すると、8文字(4文字+ 2文字+ 2文字)として出力されません。 4?

私は明らかにCがバックスペースをどのように処理するのか誤解しています。また、コードが変数をどのようにインクリメントするのですか?nc

+4

編集は端末アプリケーションによって処理されるので、 'getchar'は決して削除を読みません。 –

+0

注:前者は標準に従って有効なものなので、 'main()'の代わりに 'int main(void)'を使うべきです。 –

+0

@CoolGuy:実際、2番目のバージョンはまだ有効ですが、遺産です。これは陳腐化機能であり、標準から削除される可能性があります。言った:はい、最初のバージョンを確実に使用すべきです。一般に、プロトタイプ形式の署名は、一般的な関数に使用する必要があります。 – Olaf

答えて

5

通常、端末セッションは「回線モード」で実行されています。つまり、回線が完了したとき(たとえば、Returnキーを押したときなど)にだけデータをプログラムに渡します。そのため、行が完成した時点でしか行が表示されません(プログラムを編集する前に編集が完了している)。通常、これは良いことですので、すべてのプログラムは削除などを処理する必要はありません。

ほとんどのシステム(Unixベースのシステムなど)では、端末を「生」モードにすることができます。つまり、各文字は受け取ったものとしてプログラムに渡されます。例えば、画面指向のテキストエディタが一般的にこれを行います。

5

getchar()は「削除」をカウントしませんが、ターミナル・ドライバによってプログラムに渡されるまで入力が表示されません。

何かを入力すると、\nを押すかEOF(またはEOL)を送信するまで、Cプログラムには到達しません。これは、POSIXが定義するもので、通常はデフォルトのモードであるCanonical Mode Input Processingです。

+0

右、そうです。だから、これはCコードそのものではなく、ターミナルの仕組みを誤解しています。 –

1

バックスペース文字は、通常、調理済みttyモード(BSDのtty(4)とLinuxシステムのtermios(3)の正規入力モードを参照)で入力を編集するために使用されるため、ttyドライバで消費され、プロセスはそれ以降になります。ファイルの末尾にはCtrl-D、キル入力文字としてはCtrl-Kも同様です。ドライバーがあなたのプロセスが最終的には得られないシーンの中でいくつかのことがあります。あなたの人生で入力が消去されることを避けたいのであれば、通常はユーザーやプログラマーの方が楽になるように指示されています。また、末尾が\n\rでないようにしたい場合は、 [RETURN]キーを押します。しかし、バックスペースを持つファイルから読み込んだ場合は、通常の入力としてそれらを取得し、バックスペースを含むファイルを作成し、そこから入力をリダイレクトしようとすると、その文字が入力に表示されます。

ところで、ターミナルでバックスペースを生成したい場合は、それぞれの前にCtrl-V文字を追加してください(これはttyドライバでも管理されており、ファイルから読み込んだときには発生しません)。ファイルの普通の入力としてのバックスペース文字(Ctrl-Vを二重に送る)

関連する問題