200

In C, printing to standard output (stdout) is easy, with printf from stdio.h.

However, how can I print to standard error (stderr)? We can use fprintf to achieve it apparently, but its syntax seems strange. Maybe we can use printf to print to standard error?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
wad
  • 2,491
  • 3
  • 14
  • 16

7 Answers7

286

The syntax is almost the same as printf. With printf you give the string format and its contents ie:

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

With fprintf it is the same, except now you are also specifying the place to print to:

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

Or in your case:

fprintf(stderr, "my %s has %d chars\n", "string format", 30);
Per Lundberg
  • 3,837
  • 1
  • 36
  • 46
Fantastic Mr Fox
  • 32,495
  • 27
  • 95
  • 175
56

Some examples of formatted output to stdout and stderr:

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
  • 208,748
  • 37
  • 389
  • 560
21
#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 is usually unbuffered and stdout usually is. This can lead to odd looking output like this, which suggests code is executing in the wrong order. It isn't, it's just that the stdout buffer has yet to be flushed. Redirected or piped streams would of course not see this interleave as they would normally only see the output of stdout only or stderr only.

  2. Although initially both stdout and stderr come to the console, both are separate and can be individually redirected.

hasectic saif
  • 311
  • 1
  • 2
  • 3
8

If you don't want to modify current code and just for debug usage.

Add this macro:

#define printf(args...) fprintf(stderr, ##args)
// Under GCC

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

Change stderr to stdout if you want to roll back.

It's helpful for debug, but it's not a good practice.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
lxiange
  • 89
  • 1
  • 3
  • 2
    You could also give it a separate name, perhaps `eprintf` or something. (:O This is actually GCC (3.2)'s example of a variadic macro: https://gcc.gnu.org/onlinedocs/gcc-3.2/cpp/Variadic-Macros.html) – Solomon Ucko Aug 15 '20 at 19:27
2

You may know sprintf. It's basically the same thing with fprintf. The first argument is the destination (the file in the case of fprintf i.e. stderr), the second argument is the format string, and the rest are the arguments as usual.

I also recommend this printf (and family) reference.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
-1

For some reason, no one has mentioned eprintf() yet, which is the same thing as fprintf(stderr, ...).

eprintf("ERROR: You have caused an error!!1!");

Quick tip: If you are using stderr for debugging, you can use the __LINE__ macro

#define printfError(str, ...) eprintf("ERROR at line " #__LINE__ ": " str, __VA_ARGS__)

printfError("Division by zero"); // "ERROR at line 2: Division by zero
-7

To print your context, you can write code like this:

FILE *fp;
char *of;
sprintf(of, "%s%s", text1, text2);
fp = fopen(of, 'w');
fprintf(fp, "your print line");
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
winterli
  • 68
  • 6