Why use stderr when printf works fine? - c

Why should we use stderr when printing a custom error message from printf works fine?
For example why use stderr at all when I can just write a statement like this:
printf("error! you didn't... blah blah blah");

It is good practice to redirect all error messages to stderr, while directing regular output to stdout. It is beneficial to do this because anything written to stderr is not buffered, i.e., it is immediately written to the screen so that the user can be warned immediately.

stderr stands for standard error stream.
In console programming, it is the console -- the screen. It is essentially the same as stdout.
The general practice is to redirect all error messages to stderr and all regular output to stdout.
The reason is that it is possible to redirect standard output to a file instead of the screen. So If you perform a dir > dirlist.txt command on the command prompt, the directory listing goes into the text file instead of the screen. If you code to redirect error messages to stderr, the errors will always go to the screen instead of the file so that the user could be warned immediately instead of ending up seeing unexpected results in the file.
Using printf() will display the error message to the console, which will be stored in the stdout buffer, but using stderr, is different.
stderr can be used as an argument for any function that takes an argument of type FILE* expecting an output stream, like fputs or fprintf.
Although in many cases, both stdout and stderr are associated with the same output device (like the console), applications may differentiate between what is sent to stdout vs stderr for situations when one of them is redirected. For example, it is a common practice to redirect the regular output of a console program (stdout) to a file, while expecting the error messages to keep appearing in the console.
It is also possible to redirect stderr to another destination from within a program using the freopen function.
Also, stderr is never fully buffered on startup. It is library-dependent whether the stream is line-buffered or not-buffered by default (see setvbuf).

It is a good practice.
Lets say you use linux. If so, you can run your program following way:
./program >out 2>errout
'out' file will contain only STDOUT.
'errout' file will contain only STDERR
So if your output is hundreds of lines long, it is easier to look for few errors in 'errout' rather than look through tons of non-error lines combined with error lines.

If you redirect your program's output into a file you still would want to see the errors on screen.

In addition to stderr not being buffered, it is also nice to split output into errors vs. normal output to allow other programs to use of your program more easily. That way, the calling program can redirect standard or error output selectively depending on what it needs to know. This same facility can be used manually through Unix shells - here's one way I use that sometimes:
% find / -iname hello.txt
find: /.DocumentRevisions-V100: Permission denied
find: /.fseventsd: Permission denied
find: /.MobileBackups: Permission denied
find: /.Spotlight-V100: Permission denied
find: /.Trashes: Permission denied
^C
% find / -iname hello.txt 2>/dev/null <-- filter "Permission denied" errors

Related

What is the difference between stdout and stderr in C?

In C, stdout and stderr both print to the console window by default. Is there any difference between stderr and stdout other than the level of buffering?
One of the differences between stdout and stderr is the level of buffering. In §7.21.3 Files ¶7, the C11 standard says:
At program startup, three text streams are predefined and need not be opened explicitly -- standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.
Typically, that means that standard output is line buffered (so the data is flushed when a newline is printed, or when the buffer is full), whereas standard error is either line buffered or unbuffered. These characteristics can be changed, of course.
The purpose of the standard error stream is to separate error messages from regular output. This is important in contexts such as shell scripts, where the standard output might be sent to a pipe or to a file. That redirection leaves standard error still going to a different place — usually the terminal. You can capture the standard output separately from the standard error too, at least if the shell is sufficiently powerful.
program > file
program | filter
program 2> error.log | filter
program > file 2> error.log
program 2> error.log
The first two leave the error messages visible on the terminal. The last three capture the error messages in the file error.log — sending the standard output to the filter program, the file or to the terminal window respectively.
By separating the error messages from the standard output, the programs down the pipeline (filter in my example) don't have to interpret the error messages from program, which makes them much, much simpler.
If running a program from the console, or via a batch file, or via a shortcut, use > or 1> to redirect stdout to a file, and use 2> to redirect stderr to a file. For example if reading from stdin, and writing to both stdout and stderr:
myprog <input.txt >output.txt 2>error.txt
or if you want stdout to a file, but stderr to display on the screen, use:
myprog <input.txt >output.txt
stderr is - well - the place for errors. It is really useful. Like make - if a program's return code is not 0 (it completed with errors), it will print stderr. stderr can not be differentiated from stdout by the user, but it's still the recommended place for errors. However, if your program will be run by any automatization program, shell script etc... it can be used to track errors, and always use it.

is there a way to distinguish stderr in console output?

That is display both streams on console but distinguish somehow one from another.
Normally is that I don't know which lines are stderr they are mixed with normal output. If I redirect it to a file then I don't know when in relation to normal output the error happened. So is there a way so every line that comes from stderr would have some indicator like for example a string at the beginning like this:
c:\>command.exe
normal output
normal output
normal output
stderr: error message
normal output
stderr: error message
normal output
This is especially problem in compilers/make which spew lot of information and mix those two streams. I know I can prepend every line of text with given string using unix sed but I do not know how to use it with relation to main program. If I join two streams string will be prepended to every line. If I redirect stderr to file it won't be displayed on console + it will get out of context from stdout.
If the purpose is to distinguish error messages from normal output in the same screen, then it may be done via this trick:
anycompiler params ... 2>&1 1>&3 | findstr /N /A:4E "^"
This way the error messages appears preceded by a line number in yellow color on red background.
Previous answer extracted from: Batch - How can I redirect stderr and stdout from within the batch script itself?
If you redirect both outputs of previous line to a disk file, STDERR output will be preceded by a line number.

Where does stderr file dumps its content to?

I wanted to know like where does the stderr dumps its content.
I have a question like whether it dumps to syslog?
Please explain.
stderr is just another output stream, just like stdout.
Where it's hooked up depends on how the application is called.
For example if I run foo.exe 2> errors.txt then stderr will write to the specified file.
Stderr output is dumped whenever you decide to redirect it.
If you run a program in a GUI enviroment, by clicking on an icon or something, look for .xsession-errors in your $HOME.
If you run a program from a shell and don't redirect stderr, you just see it on your terminal (and it is not saved anywhere else).
That depends on the environment.
By default, stderr is typically connected to the same place as stdout, i.e. the current terminal.
Otherwise, you wouldn't see the errors which would be kind of annoying.
Here is a blog post about redirecting stderr to the system's logging mechanism.
stderr is a stream. It's managed by and output to by the owning process. Where it 'goes' is defined by how the process is invoked. The parent process can gather it and write it to a file, ignore it, redirect it to /dev/null (esssentially binning it) etc.
Whilst stderr can be redirected elsewhere, it typically outputs to the same place as stdout. To make it into syslog, you'd definitely have to work a bit. This link:
With bash, how can I pipe standard error into another process?
shows how you pipe stderr to a pipe, and if the other process is a process that writes to "syslog", it would do what you want. But for most cases, it's probably easier to just add syslog functionality to your own program.

C program output should go to console, but should not be redirectable

I want my_custom_print() output to appear on console. But if the program's stderror or stdout is redirected from shell, they should get redirected (as normal), but the output from my_custom_print() should get ignored.
Is it possible to write my_custom_print() satisfying above condition ? If possible, how?
You can try opening /dev/tty, but it doesn't necessarily exist, if your program run from the environment with no tty.
Maybe isatty or /dev/tty could be useful to you.

How to redirect the output of a c program to a file?

I am trying to redirect the output of a c program to file, even when it generates some errors because of problems with the input data. I can send the output but the error messages to a file.
Does somebody know how to do it?
From within C source code, you can redirect outputs using freopen():
General outputs:
freopen("myfile.txt", "w", stdout);
Errors:
freopen("myfile_err.txt", "w", stderr);
(This answer applies to bash shell, and similar flavors. You didn't specify your environment and this sort of question needs that detail.)
I assume you know about basic redirection with ">". To also capture STDERR in addition to STDOUT, use the following syntax:
command > file-name 2>&1
For some more background on standard streams and numbers:
http://en.wikipedia.org/wiki/Standard_streams#Standard_input_.28stdin.29
This depends on what you mean and what platform you are using. Very often you can accomplish this from the command line, which has been covered in another answer. If you use this method to accomplish this you should be aware that FILE * stderr is typically written immediately (unbuffered) while FILE * stdout may be buffered (usually line buffered) so you could end up with some of your error messages appearing to have been printed earlier than some other messages, but actually the other messages are just being printed late.
From within a C program you can also do something similar within the stdio system using freopen, which will effect the FILE *, so you could make fprintf(stderr, "fungus"); print to something besides what stderr normally would print to.
But if you want to know how to make a program redirect the actual file descriptors under a unix like system you need to learn about the dup and dup2 system calls. They allow you to duplicate a file descriptor.
int fd = open("some_file", O_WRONLY);
dup2(2,fd);
close(fd);
This code will make "some_file" the new stderr at the OS level. The dup2 call will close and replace file descriptor 2 (stderr, which is usually used by FILE * stderr but not necessarily if you call freopen(x,y,stderr) since that may make FILE *stderr use a different file descriptor).
This is how shell programs redirect input and output of programs. The open all of the files that the new program will need, fork, then the child uses dup2 to set up the files descriptors for the new program, then it closes any files that the new program won't need (usually just leaving 0, 1, and 2 open), and then uses one of the exec functions to become the program that the shell was told to run. (some of this isn't entirely accurate because some shells may rely on close on exe flags)
Using a simple linux command you can save the output into the file. here is a simple linux terminal command.
ls > file.txt
The output of this command will be stored into the file.
same as you can store the output of the program like this suppose, object file name is a, run the following command to save output in a file:
./a > file.txt

Resources