getchar()関数の思考と総括

3068 ワード

getchar()関数といえば、最も典型的な例は「The C Programming Language」の例です.
#include <stdio.h> 
 
   /* copy input to output; 2nd version  */ 
   main() 
   { 
       int c; 
 
       while ((c = getchar()) != EOF) 
           putchar(c); 
   } 

=====================================================================================================
C 99のEOFの説明は以下の通りである.
which expands to an integer constant expression, with type int and a negative value, that
is  returned  by  several  functions  to  indicate end-of-file, that  is,  no  more  input  from  a
stream;

EOFはint型の負数定数であることが分かる(一般的にはEOFマクロを-1と定義する)
=====================================================================================================
 
*********************************************************************************************************************************************
まず、getcha()関数の戻り値がint型である理由を説明します.
ネットワーク上の説明は次のとおりです.
char型はすべての文字を収容できません.特に、EOFを収容できない可能性があります.そのため、次のような問題が発生します.
①一部の合法的な入力文字が「切り捨て」された後の値がEOFと等しい場合があり、これによりプログラムが早期に終了する
②char型ではEOFの値を取ることが不可能であり、プログラムデッドサイクルを招く
③一部のコンパイラは確かに関数の戻り値を切り取り、ローエンドバイトをchar型にコピーしているが、cとEOFを比較する際に関数の戻り値とEOFを比較しているため、cをchar型と宣言する際のプログラムの実行が正しい.
 
私の疑問は以下の通りです.
①getchar()関数が返す値は果たしてすべてASCIIなのでしょうか(ASCIIの範囲は0~127)?もしそうであれば、切り取りが発生しても結果には影響しません.上位は0ですから.そうでなければ(例えば漢字)では、切り出し後の値がEOFと等しい可能性があり、例えば0 x 000001 ffの値を返し、切り出し後の値がEOFであると明らかにエラーが発生する.
問題はgetchar関数が漢字を処理できるかどうかですが、試してみましたが、できます.
②標準EOFはint型の負定数と言うだけで、-1ではなく他の負の値があるのではないでしょうか.
 
もしgetchar関数がASCIIコードの範囲内の数字しか処理できないならば、私達はcがsigned char(-128~127)であることを宣言する行を表示してはいけませんか?だめであるべきで、EOFはこの範囲内に値を取らない可能性があります(例えば-129).
 
以上、int cを推奨します.これは間違いないからです.
http://blog.sina.com.cn/s/blog_6057ff5301014e0t.html
*********************************************************************************************************************************************
 
2つ目に議論したいのは,このプログラムの入出力に関する問題である.
まず理解しなければならないのはgetchar関数が行為単位でアクセスされていることですが、どういう意味ですか?
プログラムを実行すると、文字を入力すると文字が表示されるのではなく、車に戻ってから入力した文字を一緒に表示し、改行して再入力を待つことに気づきました.
入力した文字はすぐに画面に表示されるのではなく、キーボードバッファに保存され、リターンキーを押してからバッファからプログラムに送信されます.
みんなが考えたことがあるかどうか分かりませんが、私たちは車に戻るのにどうして改行したのですか?折り返しは改行のASCIIとは違いますね
したがって、リターンキーを押すと、①リターンキーではなくバッファの最後に改行記号を追加し、②バッファの内容を私たちのプログラムに送信します.私たちのプログラムは、送信されたプログラムを受信して画面に文字を印刷し、別の行の開始で入力を待っています.
注意、なぜ別の行の始まりなのか.改行文字は改行するだけで、行のどこにいてもかまいません.
もとのプログラムはデータを受け取った後に、私達のデータを変えて、もとのデータはxxxで、変えた後にxxxr.になりました
プロセス全体は次のようにまとめられています.
①プログラムはユーザーがリターンキーを押してからデータを受信する
②プログラムは、ユーザが入力したリターン(ASCIIコードは13)を改行文字(ASCIIコードは10)とする
③プログラムは改行文字を送信しているが、端末は折り返し改行文字を受信している
 
プログラム受信EOFについては2つの状況に分けて決める.
1つ目は、バッファに文字がある場合です.この場合、プログラムはバッファに何も追加せず、バッファの内容をそのまま印刷し、入力を待っています.
2つ目は、バッファに文字がない場合であり、この場合、プログラムは、バッファにEOFで表される数値をそのまま追加するので、プログラム条件が成立して終了する.
stty rawコマンドで端末のプロパティを変更すると、文字を入力するとすぐに文字が表示され、EOFは効果がなく、Ctrl+Cさえ中断できないことに気づきました.その中で、システムがどのようにこれらのメカニズムを実現しているのかを理解する必要があります.