¿Cómo puedo imprimir en stderr en C?

119

En C, imprimir en salida estándar es fácil, con printffrom stdio.h.

Sin embargo, ¿cómo puedo imprimir en stderr? Podemos utilizar fprintfpara lograrlo aparentemente, pero su sintaxis parece extraña. ¿Quizás podamos usar printfpara imprimir en stderr?

taco
fuente
5
¿Qué tiene de "extraño" su sintaxis? Es imprimir dónde , cómo y qué .
Eugene Sh.
5
Me estoy enfocando en eso. El único problema que surge de la pregunta es que encuentras la solución "extraña". De lo contrario, no hay duda. Utilice fprintf.
Eugene Sh.
@Eugene. Estoy de acuerdo contigo. Pensé que era extraño porque no me di cuenta de que stderr es un ARCHIVO :)
wad

Respuestas:

179

La sintaxis es casi la misma que printf. Con printfle da el formato de cadena y su contenido, es decir:

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

Con fprintfél es lo mismo, excepto que ahora también está especificando el lugar donde imprimir:

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

O en tu caso:

fprintf( stderr, "my %s has %d chars\n", "string format", 30);
Fantástico señor zorro
fuente
34

Ejemplos:

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
fuente
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 generalmente no tiene búfer y stdout generalmente lo es. Esto puede llevar a una salida de apariencia extraña como esta, lo que sugiere que el código se está ejecutando en el orden incorrecto. No lo es, es solo que el búfer de salida estándar aún no se ha vaciado. Los flujos redirigidos o canalizados, por supuesto, no verían esta intercalación, ya que normalmente solo verían la salida de stdout only o stderr only.

  2. Aunque inicialmente tanto stdout como stderr llegan a la consola, ambos están separados y se pueden redirigir individualmente.

saif hasectico
fuente
5

¿Sabe usted sprintf? Es básicamente lo mismo con fprintf. El primer argumento es el destino (el archivo en el caso de fprintfie stderr), el segundo argumento es la cadena de formato y el resto son los argumentos como de costumbre.

También recomiendo esta printfreferencia (y familiar) .

Algún tipo programador
fuente
5

Si no desea modificar los códigos actuales y solo para el uso de depuración.

Agregue esta macro:

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

Cambie stderra stdoutsi desea retroceder.

Es útil para la depuración, pero no es una buena práctica.

lxiange
fuente
0

Para imprimir su contexto, puede escribir código como este:

FILE *fp;
char *of;
sprintf(of,"%s%s",text1,text2);
fp=fopen(of,'w');
fprintf(fp,"your print line");
Winterli
fuente
Esto no agrega nada a las respuestas anteriores y realmente no responde a la pregunta.
Fantastic Mr Fox
¡Esa declaración sprintf () causa corrupción de memoria! ... Le recomiendo que lea sobre cómo funcionan los punteros, matrices y cadenas.
BlueChip