Como posso imprimir em stderr em C?

119

Em C, imprimir em stdout é fácil, com printffrom stdio.h.

No entanto, como imprimir em stderr? Podemos usar fprintfpara alcançá-lo aparentemente, mas sua sintaxe parece estranha. Talvez possamos usar printfpara imprimir em stderr?

maço
fonte
5
O que há de tão "estranho" em sua sintaxe? É imprimir onde , como e o quê .
Eugene Sh.
5
Estou me concentrando nisso. O único problema que surge da pergunta é que você acha a solução "estranha". Caso contrário, não há dúvida. Use fprintf.
Eugene Sh.
@Eugene. Eu concordo com você. Achei estranho porque não percebi que stderr é um ARQUIVO :)
wad

Respostas:

179

A sintaxe é quase a mesma que printf. Com printfvocê fornece o formato da string e seu conteúdo, ou seja:

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

Com fprintfele é o mesmo, só que agora você também está especificando o local para imprimir:

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

Ou no seu caso:

fprintf( stderr, "my %s has %d chars\n", "string format", 30);
Fantástico Sr. Fox
fonte
33

Exemplos:

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
fonte
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 é geralmente sem buffer e stdout geralmente é. Isso pode levar a uma saída de aparência estranha como esta, o que sugere que o código está sendo executado na ordem errada. Não é, só que o buffer stdout ainda não foi limpo. Streams redirecionados ou canalizados, é claro, não veriam essa intercalação, pois normalmente veriam apenas a saída de stdout apenas ou apenas de stderr.

  2. Embora inicialmente tanto stdout quanto stderr venham para o console, ambos são separados e podem ser redirecionados individualmente.

saif hassético
fonte
5

Você sabe sprintf? É basicamente a mesma coisa com fprintf. O primeiro argumento é o destino (o arquivo no caso de fprintfie stderr), o segundo argumento é a string de formato e os demais são os argumentos, como de costume.

Eu também recomendo esta referência printf(e família) .

Algum cara programador
fonte
5

Se você não deseja modificar os códigos atuais e apenas para uso de depuração.

Adicione esta macro:

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

Altere stderrpara stdoutse quiser reverter.

É útil para depurar, mas não é uma boa prática.

lxiange
fonte
0

Para imprimir seu contexto, você pode escrever um código como este:

FILE *fp;
char *of;
sprintf(of,"%s%s",text1,text2);
fp=fopen(of,'w');
fprintf(fp,"your print line");
Winterli
fonte
Isso não acrescenta nada às respostas anteriores e realmente não responde à pergunta.
Fantástico Sr. Fox
Essa instrução sprintf () causa corrupção de memória! ... Eu recomendo fortemente que você leia sobre como ponteiros, matrizes e strings funcionam.
BlueChip