2

この K&R の例に関するサイトを見回したところ、答えは「なぜこれは int 型なのか、それとも EOF なのか?」を中心に展開しているようです。ちょっとみんな。私はそれらを理解していると信じています。よく分からない結果です。私は、このコードが 1 文字を取り、それを出力してから、別の文字または EOF を待つことを期待していました。

私が見る結果は、リターンを押すまで入力を待っていることです。その後、入力したすべてが表示され、さらに入力を待っています。

テキストストリームをcarrage returnで終了し、putchar(c)がどこかに隠れているかを表示するまで、whileループは単に「ループ」していますか?

コードは次のとおりです。

#include <stdio.h>

/* copy input to output: 1st version */
main()
{
    int c;

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

ここで、while の直前の行の前に putchar(c) をこっそり入力すると、期待どおりの結果が得られます。テキスト ストリームを入力して Return キーを押す必要があります。結果はストリームの最初の文字になり、プログラムは終了します。

明らかに、私が行っている大きな絵のギャップがあります。

ご協力ありがとうございました

4

2 に答える 2

2

デフォルトでは、stdin と stdout はバッファリングされます。つまり、文字のバッチを保存し、効率のために一度に送信します。通常、バッチは、バッファーに余裕がなくなるか、ストリームに改行または EOF が存在するまで保存されます。

を呼び出すときはgetchar()、stdin の文字から質問しています。と入力するAと、その文字はバッファに保存され、システムは次の入力を待ちます。と入力するBと、その文字が次にバッファに入ります。おそらくその後、Enter キーを押すと、バッファに改行が挿入されます。ただし、改行もバッファリング プロセスを中断するため、元の への呼び出しgetchar()はバッファ内の最初の文字を返します ( A)。次の反復でgetchar()再度呼び出すと、すぐにバッファ内の次の文字が返されます ( B)。等々。

そのため、行を終了するまで while ループが実行されているわけではありません。getchar()(バッファーが空の場合) への最初の呼び出しは、バッファーがいっぱいになるか、改行が表示されるまで待機しています。

のような出力関数をインターリーブするとputchar()、ほとんどの C ランタイム ライブラリは、データを stdout に送信する何かを実行したときに stdin を「フラッシュ」します (逆も同様です)。putchar()(目的は、プログラムが入力を待つ前にユーザーにプロンプ​​トが表示されるようにすることです。)呼び出しを追加したときに、異なる動作が見られるようになったのはそのためです。

関数を使用してバッファを手動でフラッシュできflush()ます。を使用して、標準ストリームが使用するバッファのサイズを制御することもできますsetvbuf()

Han Passant がコメントで指摘したように、改行は「ストリームを終了」しません。標準入力で EOF を取得するには、Ctrl+D (または、一部のシステムでは Ctrl+Z) を入力する必要があります。EOF もバッファをフラッシュします。ファイルまたは別のプログラムからの出力を stdin にリダイレクトした場合、その入力が使い果たされると EOF が発生します。

K&R C が非常に古いことは事実であり、ANSI C でさえ今日ほど一般的ではありませんが、stdin と stdout によるバッファリングに関するすべては、現在の標準でも C++ でも事実上同じです。唯一の重要な変更点は、C 標準が、stdin と stdout を使用して他方をフラッシュすることが望ましいと明示的に呼びかけていることだと思います。

于 2016-04-18T21:09:08.023 に答える