Bagaimana saya bisa mencetak ke stderr di C?

120

Di C, Mencetak ke stdout itu mudah, dengan printfdari stdio.h.

Namun, bagaimana cara mencetak ke stderr? Kita dapat menggunakannya fprintfuntuk mencapainya, tetapi sintaksnya tampak aneh. Mungkin bisa kita gunakan printfuntuk mencetak ke stderr?

gumpalan
sumber
5
Apa yang "aneh" tentang sintaksnya? Ini mencetak di mana , bagaimana dan apa .
Eugene Sh.
5
Saya fokus padanya. Satu-satunya masalah yang muncul dari pertanyaan, bahwa Anda menemukan solusi "aneh". Kalau tidak, tidak ada pertanyaan. Gunakan fprintf.
Eugene Sh.
@Tokopedia Saya setuju denganmu. Saya pikir itu aneh karena saya tidak menyadari stderr adalah FILE :)
wad

Jawaban:

179

Sintaksnya hampir sama dengan printf. Dengan printfAnda berikan format string dan isinya yaitu:

printf("my %s has %d chars\n", "string format", 30);

Dengan fprintfitu adalah sama, kecuali sekarang Anda juga menentukan tempat untuk mencetak ke:

File *myFile;
...
fprintf( myFile, "my %s has %d chars\n", "string format", 30);

Atau dalam kasus Anda:

fprintf( stderr, "my %s has %d chars\n", "string format", 30);
Tuan Fox yang fantastis
sumber
34

Contoh:

printf("%s", "Hello world\n");              // "Hello world" on stdout (using printf)
fprintf(stdout, "%s", "Hello world\n");     // "Hello world" on stdout (using fprintf)
fprintf(stderr, "%s", "Stack overflow!\n"); // Error message on stderr (using fprintf)
Paul R
sumber
9
#include<stdio.h>

int main ( ) {
    printf( "hello " );
    fprintf( stderr, "HELP!" );
    printf( " world\n" );
    return 0;
}

$ ./a.exe
HELP!hello  world
$ ./a.exe 2> tmp1
hello  world
$ ./a.exe 1> tmp1
HELP!$
  1. stderr biasanya unbuffered dan stdout biasanya. Hal ini dapat menyebabkan keluaran yang tampak aneh seperti ini, yang menunjukkan bahwa kode dijalankan dalam urutan yang salah. Tidak, hanya saja buffer stdout belum di-flush. Aliran yang dialihkan atau disalurkan tentu saja tidak akan melihat interleave ini karena mereka biasanya hanya melihat output dari stdout saja atau stderr saja.

  2. Meskipun pada awalnya stdout dan stderr datang ke konsol, keduanya terpisah dan dapat dialihkan satu per satu.

hasectic saif
sumber
5

Tahukah kamu sprintf? Itu pada dasarnya sama dengan fprintf. Argumen pertama adalah tujuan (file dalam kasus fprintfie stderr), argumen kedua adalah format string, dan sisanya adalah argumen seperti biasa.

Saya juga merekomendasikan referensi ini printf(dan keluarga) .

Beberapa programmer
sumber
5

Jika Anda tidak ingin mengubah kode saat ini dan hanya untuk penggunaan debug.

Tambahkan makro ini:

#define printf(args...) fprintf(stderr, ##args)
//under GCC
#define printf(args...) fprintf(stderr, __VA_ARGS__)
//under MSVC

Ganti stderrkestdout jika Anda ingin memutar kembali.

Ini membantu untuk debug, tetapi ini bukan praktik yang baik.

lxiange
sumber
0

Untuk mencetak konteks Anda, Anda dapat menulis kode seperti ini:

FILE *fp;
char *of;
sprintf(of,"%s%s",text1,text2);
fp=fopen(of,'w');
fprintf(fp,"your print line");
winterli
sumber
Ini tidak menambahkan apapun pada jawaban sebelumnya dan tidak benar-benar menjawab pertanyaan tersebut.
Tuan Fox yang fantastis
Pernyataan sprintf () itu menyebabkan kerusakan memori! ... Saya sangat menyarankan Anda membaca tentang cara kerja pointer, array, dan string.
BlueChip