Difference between puts() and printf() in C while using sleep()
Asked Answered
T

3

8

I was wondering the difference between puts() and printf() functions while using sleep() function.

Here is my code(In C language):

printf("hello, world");
sleep(1);
printf("Good, bye!");

After compiling and running the program, it seems that it will sleep first and then print "hello, worldGood, bye!"

However, if using puts() instead of printf(), it will print "hello, world" then sleep, and finally print "Good, bye".

puts("hello, world");
sleep(1);
puts("Good, bye!);
Trilogy answered 4/2, 2013 at 4:10 Comment(0)
P
12

This is because of buffering - by default, standard out buffers up to each new line. printf() does not include a newline, so output isn't flushed. puts() includes a newline, so output is flushed.

You can cause printf() to flush by putting a newline:

printf("hello, world\n");

or by calling fflush() directly:

fflush(stdout);

For more about buffering, see the man page for setbuf():

The three types of buffering available are unbuffered, block buffered, and
   line buffered.  When an output stream is unbuffered, information appears on
   the destination file or terminal as soon as written; when it is block 
   buffered many characters are saved up and written as a block; when it 
   is line buffered characters are saved up until a newline is output or input
   is read from any stream attached to a terminal device (typically stdin).
   ....
   If a stream refers to a terminal (as stdout normally does) it is 
   line buffered. 
   ....
   The standard error stream stderr is always unbuffered by default.
Push answered 4/2, 2013 at 4:13 Comment(0)
G
9

It's because puts is also outputting a newline character which, on devices that can be determined to be interactive, causes flushing by default (for standard output) (a).

You should see a similar effect if your initial printf outputs a newline at the end:

printf("hello, world\n");

or if you fflush (stdout); before the sleep() call.

The relevant part of C11 is 7.21.3 Files, section /7:

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.

This harks back to the days of C89/90 4.9.3 Files:

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). When 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.


(a): It's not quite that simple. For starters, this is implementation dependent simply because the standard states that what constitutes an interactive device is implementation dependent (the behaviour is specified but not the thing that affects that behaviour).

Secondly (as per here), the standard only mandates when standard output becomes fully bufferd (when the device is definitely not interactive). Whether it's unbuffered or line buffered for interactive devices is an implementation decision.

Guertin answered 4/2, 2013 at 4:12 Comment(2)
Solid answer. If you mention that the standard has been this way since C89, I'll give you the +1 that'll put you above my answer :)Push
Far be it for me to pass up some cheap rep. I just happen to have c90 lying around on the hard disk. Now I can go home and tell the wife my "never throw anything out" strategy has benefits - she won't be happy about that :-)Guertin
E
0

From what I understand, printf will flush the stream if a newline \n is present. puts, I'm not really sure. It may be implementation dependant.

Your sleep is just long enough for printf which is not containing a \n to flush the stream.

I recommend you flush the stream when required with fflush(stdout); Then you can avoid the sleep altogether.

Elizabetelizabeth answered 4/2, 2013 at 4:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.