8
#include <stdio.h>
#define MAXLEN 256

int main() {
  int n;
  char buf[MAXLEN];
  while((n = read(0,buf,sizeof(buf))) != 0){
    printf("n: %d:",n);
    write(1,buf,n);
  }
  return 1;
}

プログラムの出力(最初readと最初writeがユーザーによって入力され、端末によってエコーされる)は次のとおりです。

read
read
write
write
n: 5:n: 6:

printfの出力は、標準入力でCtrl + Dを押した後のものであり、後続の読み取りと一緒ではありません。なぜこれが起こるのですか?

4

5 に答える 5

22

Printfはバッファリングされます。

fflush呼び出しを使用して、printfにそのバッファーを「フラッシュ」させることができます。

#include <stdio.h>
#define MAXLEN 256

int main() {
  int n;
  char buf[MAXLEN];
  while((n = read(0,buf,sizeof(buf))) != 0){
    printf("n: %d:",n);
    fflush(stdout); /* force it to go out */
    write(1,buf,n);
  }
  return 1;
}

一般的に、printf()バッファリングされることは良いことです。特に画面の更新などを必要とする表示可能なコンソールへのバッファなしの出力は低速です。十分に遅いので、多くの印刷を行っているアプリケーションは、それによって直接速度を落とすことができます(特に、Windowsプラットフォームでは、LinuxとUNIXは通常影響が少ないです)。

ただし、バッファリングされていると、意図的にバッファリングprintf()されていない場合でも、問題が発生します。結果として、メッセージが欠落している可能性があります。同じく端末に関連付けられていて、バッファリングされていない可能性がある別のハンドルに書き込む場合は、最初に明示的にを確認してください。fprintf(stderr,)stderrprintf()FILEfflush(stdout)

于 2009-08-07T05:26:20.333 に答える
2

fgetsのマンページには次のように書かれています。

stdioライブラリからの入力関数への呼び出しを、入力ストリームに関連付けられたファイル記述子のread(2)への低レベルの呼び出しと混合することはお勧めできません。結果は未定義であり、おそらくあなたが望むものではありません。

したがって、最善の解決策は、同じ記述子でwriteとprintfを使用しないことです。

于 2009-08-07T12:18:31.063 に答える
1

std fflush()関数を使用してstd outバッファーをフラッシュするか、printf内の制御文字列の最後に追加の\nを使用することができます。このようなもの

printf("\n :%d:\n",n);

printf()およびscanf()の代わりに、Cでwrite()およびread()関数を使用することをお勧めします。printfとscanfには、printfが文字列パラメータをstdoutバッファに格納するなどの問題があります。したがって、手動フラッシュが必要です。これは、フラッシュ機能または\nを使用して実行されます。小さなhelloworld印刷プ​​ログラムでは、プログラムの実行の最後にstdoutバッファがフラッシュされるなどの問題は発生しません。正常に動作するwrite()を使用することをお勧めします。scanfには、スペースの読み取りの問題や、stdinバッファーに関連する他の多くの問題もあります。

たとえば、次のコードでは次のようになります。

main()  {   char a; int i=0,c; for(;i<2;i++) { scanf("%d",&c); scanf("%c",&a);} }

上記のプログラムは、Enterキーを押すと\nをstdinに読み込む問題が発生しました。これは解決できましたが、stdinバッファをフラッシュしたり、\n文字を使用したりすることはできませんでした。read()およびwrite()関数を使用することをお勧めします。

お役に立てば幸いです。

于 2012-10-08T13:33:48.240 に答える
1

Printfはstdioを使用しており、バッファリングされています。「n:%d:\ n」に変更を送信して、プッシュします。

于 2009-08-07T05:11:04.093 に答える
0

書き込みではなく、fwrite(ストリームバージョン)を使用します。

ファイル番号1に関連付けられていますが、同じものではないことに注意してください。

于 2009-08-07T19:01:35.770 に答える