9

私の生産コードのモックアップ:

/* version 1 */
#include <stdio.h>
FILE** fout = &stdout;
int main() {
     fprintf( *fout, "hello\n" );
}

gcc では問題なく動作しますが、mingw ではコンパイルに失敗すると報告されています (単項 '&' オペランドとして左辺値が必要です)。

私は見たことがあります ; という事は承知しています

/* version 2 */
#include <stdio.h>
int main() {
    FILE* fout = stdout;
    fprintf( fout, "hello\n" );
}

完全に有効です。ただし、グローバル変数を事前設定する必要があります。不運にも、

/* version 3 */
#include <stdio.h>
FILE* fout = stdout;
int main() {
    fprintf( fout, "hello\n" );
}

バージョン 1 の置き換えには適していません。gcc でさえコンパイルされません (2 行目: 初期化要素は定数ではありません)。

main() が開始する前に初期化される変数に stdout を取得する方法はありますか?

4

3 に答える 3

6

C 標準(7.21.1) によると、stdout「FILE へのポインタ」型の式であるマクロです。必ずしもグローバル変数ではありません。そのアドレスを取得するのは移植可能な C ではありません --- ご覧のとおり、gcc では機能しますが、mingw では機能しません。

コードの 2 番目のバージョンを使用してください --- これは移植可能です。

内部の初期化を移動した場合、3番目も問題ありません。foutmain

/* version 3 */
#include <stdio.h>
FILE* fout;
int main() {
    fout = stdout;
    fprintf( fout, "hello\n" );
}

この初期化を の宣言と組み合わせることはできません。これは、定数式foutstdoutはない (少なくとも、必ずしもそうとは限らない) ためです。

FILE **ポインターが必要な場合は、次を使用します。

/* version 4 */
#include <stdio.h>
FILE* mystdout;
FILE** fout = &mystdout;
int main() {
     mystdout = stdout;
     fprintf( *fout, "hello\n" );
}

mystdoutただし、同じ理由で、の初期化をその宣言で行うことはできません。

于 2013-08-29T08:19:17.533 に答える
2

ファイル記述子は一般に移植可能ではないため、これはあまり良い考えではないと思います。また、ライブラリ関数の実装が非常に低レベルになり、ファイル記述子とFILEポインターを同期するのに苦労することになります。

ただし、@ JoachimWuttkeが明示的に尋ねたように、以前のコメントで私が念頭に置いていたことは次のとおりです。

/* version 5 */
#include <stdio.h>
#include <unistd.h>

int fdout = 1;

void use(FILE *fout)
{
  fdout = fileno(fout);
}

void printing() {
  const char msg[] = "hello\n";
  write(fdout, msg, sizeof(msg)-1);
}

int main() {
  printing(); // this one goes to stdout
  FILE *f = fopen("output.txt", "wt");
  use(f);
  printing(); // this one goes to "output.txt"
  printing(); // this one too
  fclose(f);
  use(stdout);
  printing(); // this one goes to stdout too
  return 0;
}
于 2013-08-29T09:55:26.867 に答える