7

「 The C Programming Language 」 (K&R) を読み始めたのですが、関数について疑問がありgetchar()ます。

たとえば、このコード:

#include <stdio.h>

main()
{
  int c;

  c = getchar();
  putchar(c);
  printf("\n");   
}

toomanychars+ CTRL+ D(EOF) と入力すると、単にt. 最初に登場するキャラクターなので当然だと思います。

しかし、この別のコード:

#include <stdio.h>

main()
{
  int c;

  while((c = getchar()) != EOF) 
    putchar(c);
}

toomanychars+ CTRL+ D(EOF) を入力すると、 が出力されtoomanycharsます。

私の質問は、単一の char 変数しかない場合になぜこれが起こるのですか? 残りの文字はどこに保存されていますか?

編集:

答えてくれたみんなのおかげで、私は今それを手に入れ始めました...たった1つのキャッチ:

最初のプログラムはCTRL+Dを指定すると終了し、2 番目のプログラムは文字列全体を出力してから、さらにユーザーの入力を待ちます。別の文字列を待機し、最初のように終了しないのはなぜですか?

4

7 に答える 7

9

getchar標準入力 (この場合はキーボード バッファー) から 1 文字を取得します。

2 番目の例では、getchar関数は にwhile遭遇するまで継続するループ内にあるEOFため、入力が空になるまでループを継続して文字を取得 (および文字を画面に出力) します。

を連続して呼び出すとgetchar、入力からの連続する文字が取得されます。

ああ、この質問をするのは悪いことではありません。私もこの問題に最初に遭遇したときは戸惑いました。

于 2009-06-16T22:54:23.567 に答える
5

入力ストリームをファイルのように扱っています。これは、「toomanychars」というテキストを含むファイルを開いて、一度に 1 文字ずつ読み取ったり出力したりしたようなものです。

最初の例では、while ループがない場合、ファイルを開いて最初の文字を読み取り、それを出力したようなものです。ctrl+Dただし、2 番目の例では、ディスク上のファイルから読み取る場合と同様に、ファイルの終わりの信号 (この場合) を取得するまで文字を読み取り続けます。


最新の質問への回答として、使用しているオペレーティング システムを教えてください。Windows XP ラップトップで実行しましたが、問題なく動作しました。Enter キーを押すと、これまでの内容が出力され、新しい行が作成されて続行されます。(getchar()関数は、Enter キーを押すまで戻りません。これは、呼び出されたときに入力バッファーに何もない場合です)。CTRL+Z(Windows では EOF)を押すと、プログラムが終了します。Windows では、コマンド プロンプトで EOF としてカウントするには、EOF がそれ自体の行になければならないことに注意してください。この動作が Linux で模倣されているのか、それとも実行中のシステムで模倣されているのかはわかりません。

于 2009-06-16T22:53:41.993 に答える
4

ここに何かがバッファリングされています。たとえば、putchar が書き込む stdout FILE* は、line.buffered である可能性があります。プログラムが終了する (または改行に遭遇する) と、そのような FILE* は fflush() され、出力が表示されます。

場合によっては、表示している実際の端末は、改行まで、または端末自体がバッファーをフラッシュするように指示されるまで、出力をバッファーすることがあります。これは、現在のフォアグラウンド プログラムが新しいプロンプトを表示するために終了した場合に発生する可能性があります。

さて、ここで実際のケースである可能性が高いのは、(出力に加えて :-) バッファリングされるのは入力であるということです) キーを押すと、ターミナル ウィンドウに表示されます。ただし、端末はこれらの文字をアプリケーションに送信しません。Ctrl+D で入力の終わりになるように指示するまで、場合によっては改行も行うまで、端末はそれをバッファリングします。これは、遊んで熟考するための別のバージョンです。

int main() {
  int c;
   while((c = getchar()) != EOF) {
     if(c != '\n')
        putchar(c);
   }
    return 0;
}

プログラムに文を入力してみて、Enter キーを押してください。if(c != '\n') コメントアウトした場合も同じことを行いますおそらく、入力、出力、またはその両方が何らかの方法でバッファリングされているかどうかを判断できます。上記を次のように実行すると、これはさらに興味深いものになります。./mytest

(補足として、CTRL+D は文字ではなく、EOF でもないことに注意してください。ただし、一部のシステムでは、入力ストリームが閉じられ、ストリームから読み取ろうとする人に再び EOF が発生します。)

于 2009-06-16T23:03:03.380 に答える
3

最初のプログラムは 1 文字だけを読み取り、それを出力して終了します。2 番目のプログラムにはループがあります。EOF 文字を読み取るまで、文字を 1 つずつ読み取り、出力し続けます。一度に保存できる文字は 1 つだけです。

于 2009-06-16T22:55:18.667 に答える
2

変数cを使用して、各文字を一度に 1 つずつ含めるだけです。

を使用して最初の char ( t) を表示すると、変数に次の文字 ( ) を割り当て、前の値 ( ) を置き換えることputchar(c)で、 の値を忘れます。coct

于 2009-06-16T22:57:33.077 に答える
1

コードは機能的に同等です

main(){
  int c;
  c = getchar();
  while(c != EOF) {
    putchar(c);
    c = getchar();
  }
}

このバージョンの方が理解しやすいかもしれません。代入を条件に入れる唯一の理由は、'c=getchar()' を 2 回入力する必要がないようにするためです。

于 2009-06-16T23:00:53.837 に答える
0

更新された質問の場合、最初の例では、1 文字だけが読み取られます。EOF に達することはありません。printf 命令が完了した後は何もすることがないため、プログラムは終了します。1文字読むだけです。印刷します。改行を入れます。そして、それ以上何もすることがないので終了します。複数の文字を読み取ることはありません。

一方、2 番目のコードでは、getchar と putchar が while ループ内に存在します。この場合、プログラムは、EOF 文字 (^D) に到達するまで (ループによってそうするように) 文字を 1 つずつ読み取り続けます。その時点で c!=EOF にマッチし、条件を満たさないためループを抜けます。これで、実行するステートメントはなくなりました。したがって、プログラムはこの時点で終了します。

お役に立てれば。

于 2011-05-03T06:47:06.287 に答える