2016-04-18 7 views
2

私はこのK & Rの例についてサイトを見てきました。答えは「なぜこれが型intかEOFですか?ちょっと男。私はそれらを理解すると信じています。 私は理解していない結果です。私はこのコードが1文字をとり、それを印刷してから別の文字やEOFを待つことを期待していました。K&R本1.5.1ファイルコピー

私が見る結果は、私が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(); 
    } 
} 

さて、私はしばらく前の行に前のputchar(c)をこっそり場合、私は一種の私が期待したものを得ます。私はまだテキストストリームを入力し、returnキーを押す必要があります。結果はストリームの最初の文字であり、プログラムは終了します。

明らかに、私にとっては大きなギャップがあります。

はバッファリングされているデフォルトでは、標準入出力でお願い

+1

K&Rコーディングスタイルは使用しないでください。推奨されていません。 Cは最後の17年を超えて進化しました。あなたのテキストについて:**あなたの**具体的な**質問が何であるか分かりません。これはチュートリアルのサイトではありません。 – Olaf

+5

これは、標準入力と出力がバッファリングされているためです。入力した文字は、Enterキーを押すまで内部で保存され、一括して処理されます。同様に、出力文字は、改行文字を印刷するまで保存されます。このとき、すべてがフラッシュされます。入力と出力の間の直接の対応が必要な場合は、コンソールI/Oではなく特殊ライブラリを使用する必要があります。 –

+1

「CR」(別名キャリッジリターン)はストリームを終了しません。 – Olaf

答えて

2

いただきありがとうございます。つまり、効率的に一括して文字を保存して送信します。通常、バッチはバッファに空きがなくなるまで、またはストリームに改行やEOFがあるまで保存されます。

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

あなたがwhileループを実行するのは、行を終了するまでではありません。getchar()(バッファが空の場合)への最初の呼び出しは、フルバッファまたは改行があるまで待っています。

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

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

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

K & R Cが非常に古く、ANSI Cでさえもそれほど一般的ではありませんが、stdinとstdoutでバッファリングすることは、現在の標準やC++でも効果的です。私は、唯一の大きな変化は、C標準がstdinとstdoutを持つことの望ましさを明示的に呼び出すことで、他のものをフラッシュすることです。

0

ご回答いただきありがとうございます。バッファリングは非常に参考になり、面白いです。

明らかに、私は誤読/理解していなければなりません。K & R.彼らはテキストストリームを「0個以上の文字とそれに続く改行文字で構成します」と定義します。 return/enterキー。それを終了し、出力を許可します。

また、有益なご意見をいただいた皆様に感謝いたします。

ちなみに、プログラムを終了するEOFを生成するために^ Dを入力しなければならないことをはっきりと理解しました。皆さんがトップレベルのプログラマーであり、ありがとうと感謝しています。私は、この練習に関してR & Rが書いたテキストがすべてであることを議論する別の場所を見つける必要があると思います。