2016-12-07 7 views
0

ここにコードスニペットがあります。dup2が連続して発生しないのはなぜですか?

int saved_stdout = dup(1); 
int fd = open("file.txt", O_WRONLY | O_CREAT, 0640); 

close(1); 
dup(fd); 
close(fd); 

printf("This text should go into the file\n"); 

//restore stdout 
dup2(saved_stdout, 1); 
printf("stdout restore"); 

私はdupとdup2について学びたいと考えています。だから私は最初にstdoutに私のfile.txtを接続しました。だから私はprintfを使用するたびに、stdoutの代わりにfile.txtに書き込む必要があります。しかし、いったんこの使い方が終わると元に戻したいので、最後にdup2も使います。

"このテキストはファイルに保存する必要があります\ n"というテキストは、実際にはファイルには入れられませんが、stdoutには印刷されるという問題があります。なぜそうなのか?私はそれのためにひどいです。そのdup2呼び出しがそのprintf( "This text ...")の前に起こっていることがわかりました。ステートメント、なぜそう?

答えて

3

この問題は、出力バッファリングの可能性があります。 stdoutは、端末に書き込まれていない場合は完全にバッファされます。したがって、dup()でファイルにリダイレクトすると、バッファされます。 printf()の後に出力をフラッシュしてみてください。

printf("This text should go into the file\n"); 
fflush(stdout); 
+0

これは私が探していたものです。ありがとうございました – posixKing

+0

'fflush()'は動作しますが、間違った理由があると思います。 'open()'の直後に 'printf()'を置くだけで、より微妙なことが起こります。問題は、ファイル記述子とFILE構造が混在していることです。これはおそらく未定義の領域であり、異なるシステムで異なる結果が得られる可能性があります。あなたが望むことをする正しい方法は 'freopen(" file.txt "、" w "、stdout)'です。その操作は明確に定義されています。 – gilez

+0

@gilez何かを書いてファイル記述子を変更する間は、安全でなければならないと思います。私は、 'printf()'が起きた時ではなく、 'stdin'が開かれた時にバッファリングが初期化されているのではないかと思っています。しかし、それは怠惰で、最初の書き込みでそれを行うことができます。 – Barmar

0

それは間違っているように私は私の前の答えを削除し....しかし、あなたは、あなたがstdoutためFILE *を使用しているprintf()を使用する場合、その内部に記述または端末を指しているものがあります。 fd 1を変更してもそれは明らかに変更されていません。

私はテストで一貫性のない結果を得ているので、ここをあきらめてください。私はちょうどopen()後にこのラインを置くことはあいまいな行動を強調している、それは私のために働くことができますことを追加したい:

printf("fileno is %i\n", fileno(stdout)); 

は、このようなファイルディスクリプタの操作に printf()として FILE *操作を混在させないでください。記述子に write()を使用する必要があります。

+1

'dup()'は使用可能な最初のディスクリプタを使用します。彼のコードは 'dup2()'が追加される前のことです。 – Barmar

+0

@Barmar、私は混乱が "最初に利用可能"という意味を超えていると思う。それは閉鎖されているので1か、使用されていないので4ですか? – gilez

+0

私はそれが閉鎖されて以来1であるべきだと思いますか? – posixKing

関連する問題