Jak mogę drukować na stderr w C?

120

W C drukowanie na standardowe wyjście jest łatwe dzięki printffrom stdio.h.

Jednak w jaki sposób można drukować na stderr? fprintfPozornie możemy to osiągnąć, ale jego składnia wydaje się dziwna. Może możemy użyć printfdo drukowania na stderr?

zwitek
źródło
5
Co jest takiego „dziwnego” w jego składni? Wydrukuj gdzie , jak i co .
Eugene Sh.
5
Skupiam się na tym. Jedyny problem, który wynika z pytania, że ​​uważasz rozwiązanie za „dziwne”. W przeciwnym razie nie ma wątpliwości. Użyj fprintf.
Eugene Sh.
@Eugene. Zgadzam się z Tobą. Pomyślałem, że to dziwne, ponieważ nie zdawałem sobie sprawy, że stderr to PLIK :)
wad

Odpowiedzi:

179

Składnia jest prawie taka sama jak printf. Wraz z podaniem printfpodajesz format napisu i jego zawartość tj:

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

Z fprintfnim jest tak samo, z wyjątkiem tego, że teraz określasz również miejsce drukowania:

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

Lub w twoim przypadku:

fprintf( stderr, "my %s has %d chars\n", "string format", 30);
Fantastyczny pan Fox
źródło
34

Przykłady:

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.
źródło
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 jest zwykle niebuforowany, a stdout zwykle jest. Może to prowadzić do dziwnie wyglądających wyników, co sugeruje, że kod jest wykonywany w złej kolejności. Tak nie jest, po prostu bufor stdout nie został jeszcze opróżniony. Strumienie przekierowane lub potokowe oczywiście nie widzą tego przeplotu, ponieważ normalnie widzą tylko wyjście stdout lub tylko stderr.

  2. Chociaż początkowo do konsoli trafiają zarówno stdout, jak i stderr, oba są oddzielne i mogą być indywidualnie przekierowywane.

hasectic saif
źródło
5

Czy wiesz sprintf? W zasadzie to samo dotyczy fprintf. Pierwszym argumentem jest miejsce docelowe (w przypadku fprintfnp. Plik stderr), drugim argumentem jest łańcuch formatu, a reszta to zwykłe argumenty.

Polecam również to printf(i rodzinne) odniesienie .

Jakiś koleś programista
źródło
5

Jeśli nie chcesz modyfikować obecnych kodów i tylko do debugowania.

Dodaj to makro:

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

Zmień stderrna, stdoutjeśli chcesz cofnąć.

Jest to pomocne przy debugowaniu, ale nie jest dobrą praktyką.

lxiange
źródło
0

Aby wydrukować swój kontekst, możesz napisać taki kod:

FILE *fp;
char *of;
sprintf(of,"%s%s",text1,text2);
fp=fopen(of,'w');
fprintf(fp,"your print line");
winterli
źródło
To nic nie dodaje do poprzednich odpowiedzi i tak naprawdę nie odpowiada na pytanie.
Fantastyczny pan Fox
Ta instrukcja sprintf () powoduje uszkodzenie pamięci! ... Radzę przeczytać o tym, jak działają wskaźniki, tablice i łańcuchy.
BlueChip