237

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?

5
  • 18
    What's so "strange" about it's syntax? It's print where, how and what. Commented Aug 17, 2016 at 16:42
  • 8
    I am focusing on it. The only problem which is arising from the question, that you find the solution "strange". Otherwise there is no question. Use fprintf. Commented Aug 17, 2016 at 16:46
  • 2
    @Eugene. I agree with you. I thought it was strange as I did not realize stderr is a FILE :) Commented Aug 17, 2016 at 16:49
  • @Schilive Thanks for letting me know - I deleted mine now as well. Commented Apr 8, 2023 at 15:04
  • Redirect from the shell: $ ./a.out 1>&2 Commented Jan 12 at 18:20

9 Answers 9

346

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);
Sign up to request clarification or add additional context in comments.

1 Comment

You can also fprintf(stdout,…) which has exactly the same effect as printf(…)
70

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)

Comments

26
#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.

Comments

13

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.

3 Comments

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: gcc.gnu.org/onlinedocs/gcc-3.2/cpp/Variadic-Macros.html)
__VA_ARGS__ is not MSVC-specific because it is defined in section 6.10.3 paragraph 5 of C99
I agree you should not redefine printf. In general don't redefine things that already exist.
4

According to the GCC online manual, you can define a variadic eprintf macro:

#define eprintf(...) fprintf (stderr, __VA_ARGS__)

__VA_ARGS__ is a macro which expands to the variadic arguments passed to the macro, so the below code snippet

eprintf("Error message: %s", errorMessage);

will be expanded to the following.

fprintf(stderr, "Error message: %s", errorMessage);

The parameters for the function will be the same as printf.

Comments

2

While this approach does not employ the fprintf or the perror, using the system call write and fd (1) for stdout or fd (2) for stderr, same results can be achieved.

#include <stdio.h>
#include <unistd.h>

/*buff_size can vary depending on the buffer you want to write*/

int main(void){
    var[] = "Customized Error String\n";
    buff_size = 1024;

    write(1,var, buff_size);
    return (1);
}

Comments

1

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.

1 Comment

This is unrelated to the OP and is worded confusingly. sprintf will "print" to a string and cannot print to stderr.
0

I don't know what your desired scenario would be to use fprintf. In case it is to process errors, the suggested way to print errors in C is by using the perror function.

This function will print your error to stderr coupled with the interpreted errno returned from the previous function. This error is thread-local, i.e., every thread has its private value. For instance, if you try to write to a file inside of a protected directory, like in this function:

int main() {
    FILE *file = fopen("/some_write_protected_dir/file.txt", "w");
    if (file == NULL) {
        perror("Error creating file");
    } else {
        fclose(file);
    }
    return 0;
}

It will print Error creating file: Permission denied. Notice that it added the interpreted text for errno 13. Also, make sure not to have any call to other syscalls as the errno value will be overwritten.

The fprintf(stderr, ...) function on the other hand can be used to print your custom error messages.

Comments

-1

This is nonstandard but in some C implementations like Newlib, there's eprintf(), which is the same thing as fprintf(stderr, ...).

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

By the way, 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

2 Comments

Nobody mentioned eprintf because that's not a standard C library function.
@AdrianMole Oh.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.