Як я можу надрукувати на stderr на C?


119

На мові C надрукувати друк легко, з printfвід stdio.h.

Однак як можна друкувати на stderr? Ми можемо використати fprintfдля досягнення цього, мабуть, але його синтаксис здається дивним. Може, ми можемо використовувати printfдля друку на stderr?


5
Що такого "дивного" в його синтаксисі? Це друк, де , як і що .
Євген Ш.

5
Я зосереджуюсь на цьому. Єдина проблема, яка виникає з питання, що ви вважаєте рішення "дивним". Інакше питання не виникає. Використовуйте fprintf.
Євген Ш.

@Eugene. Я погоджуюсь з тобою. Я подумав, що це дивно, оскільки я не зрозумів, що stderr - ФАЙЛ :)
wad

Відповіді:


179

Синтаксис майже такий самий, як printf. З printfвами дає формат рядка і його вміст , тобто:

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

З fprintfним те саме, за винятком випадків, коли ви також вказуєте місце для друку:

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

Або у вашому випадку:

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

34

Приклади:

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)

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, як правило, не буферизований, а stdout зазвичай є. Це може призвести до виходу дивного вигляду на зразок цього, що говорить про те, що код виконує у неправильному порядку. Це не так, це просто, що буфер stdout ще не розмитий. Звичайно, перенаправлені або трубопровідні потоки не бачать цього перемежування, оскільки вони зазвичай бачать лише вихід тільки stdout або тільки stderr.

  2. Хоча спочатку і stdout, і stderr приходять до консолі, обидва є окремими і можуть бути перенаправлені індивідуально.



5

Якщо ви не хочете змінювати поточні коди та лише для налагодження.

Додайте цей макрос:

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

Змініть stderrна, stdoutякщо хочете відкати.

Це корисно для налагодження, але це не є хорошою практикою.


0

Щоб надрукувати ваш контекст, ви можете написати такий код:

FILE *fp;
char *of;
sprintf(of,"%s%s",text1,text2);
fp=fopen(of,'w');
fprintf(fp,"your print line");

Це не додає нічого до попередніх відповідей і насправді не відповідає на питання.
Фантастичний містер Фокс

Ця операція sprintf () викликає пошкодження пам'яті! ... Я настійно раджу прочитати, як працюють покажчики, масиви та рядки.
BlueChip
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.