212

I know you can print with printf() and puts(). I can also see that printf() allows you to interpolate variables and do formatting.

Is puts() merely a primitive version of printf(). Should it be used for every possible printf() without string interpolation?

alex
  • 479,566
  • 201
  • 878
  • 984
  • 62
    Just a note on using printf instead of puts: never, ever do a `printf(variable)` to print a string. Use `puts(variable)` or `printf("%s', variable)`. There's a security risk in using a variable format string: if the variable can be written by an attacker they can attack the program by using format strings. – Zan Lynx Dec 01 '12 at 09:05
  • 2
    [**puts() vs printf() - C/C++ Answers**](http://bytes.com/topic/c/answers/527094-puts-vs-printf) – Anthony Forloney Mar 16 '10 at 13:05

10 Answers10

171

puts is simpler than printf but be aware that the former automatically appends a newline. If that's not what you want, you can fputs your string to stdout or use printf.

Michael Kristofik
  • 34,290
  • 15
  • 75
  • 125
  • 11
    I think it's also important to mention the additional arguments printf take for adding additional variables into the outputted string. – Erutan409 Nov 26 '15 at 22:59
126

(This is pointed out in a comment by Zan Lynx, but I think it deserves an answer - given that the accepted answer doesn't mention it).

The essential difference between puts(mystr); and printf(mystr); is that in the latter the argument is interpreted as a formatting string. The result will be often the same (except for the added newline) if the string doesn't contain any control characters (%) but if you cannot rely on that (if mystr is a variable instead of a literal), you should not use it.

So, it's generally dangerous - and conceptually wrong - to pass a dynamic string as single argument of printf:

char * myMessage;
// ... myMessage gets assigned at runtime, unpredictable content
printf(myMessage);  // <--- WRONG! (what if myMessage contains a '%' char?)
puts(myMessage);    // ok 
printf("%s\n",myMessage); // ok, equivalent to the previous, perhaps less efficient

The same applies to fputs vs fprintf (but fputs doesn't add the newline).

leonbloy
  • 73,180
  • 20
  • 142
  • 190
  • In what way would using `printf()` be less efficient? At run time? At compile time? – franklin Jan 05 '15 at 16:51
  • 14
    @franklin at runtime, because `printf` needs to parse the format string. However, this should normally be irrelevant. Further, a clever compiler could optimize this, and replace the `printf` with call to `puts` – leonbloy Jan 06 '15 at 14:12
41

Besides formatting, puts returns a nonnegative integer if successful or EOF if unsuccessful; while printf returns the number of characters printed (not including the trailing null).

echristopherson
  • 6,974
  • 2
  • 21
  • 31
  • 1
    When I've tested this, puts returns the number of characters in the string including the terminating character, whereas printf returns the number of characters printed without the terminating character. Which is technically consistent with your definition, as the former is a non-negative integer, but I'm not sure whether that's what you meant to say. – Lou Apr 22 '21 at 16:13
  • @lou, are you sure the extra including come from the null terminator but not the '\n'? – diverger Jan 15 '22 at 00:25
21

In simple cases, the compiler converts calls to printf() to calls to puts().

For example, the following code will be compiled to the assembly code I show next.

#include <stdio.h>
main() {
    printf("Hello world!");
    return 0;
}
push rbp
mov rbp,rsp
mov edi,str.Helloworld!
call dword imp.puts
mov eax,0x0
pop rbp
ret

In this example, I used GCC version 4.7.2 and compiled the source with gcc -o hello hello.c.

apaderno
  • 28,547
  • 16
  • 75
  • 90
Hannu Balk
  • 257
  • 2
  • 5
12

In my experience, printf() hauls in more code than puts() regardless of the format string.

If I don't need the formatting, I don't use printf. However, fwrite to stdout works a lot faster than puts.

static const char my_text[] = "Using fwrite.\n";
fwrite(my_text, 1, sizeof(my_text) - sizeof('\0'), stdout);

Note: per comments, '\0' is an integer constant. The correct expression should be sizeof(char) as indicated by the comments.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
  • 2
    "fwrite to stdout works a lot faster than puts." - What could possibly be the reason? – Antony Hatchkins Mar 15 '13 at 13:08
  • 7
    @AntonyHatchkins It's typically not "a lot" faster. puts(), however, does have to perform an strlen() call every time on your string whereas if the size is known with fwrite() it can be avoided. That's pretty much the only real contributer to a performance difference. – Wiz Nov 18 '13 at 08:54
  • 13
    This answer is incorrect. `'\0'` has type `int`, so on most systems this will print `Using fwrit`. If you want to print 1 less byte, just use 1. `sizeof (char)`, which is likely what you intended here, is guaranteed to be 1. – Bradley Garagan Aug 17 '15 at 18:32
11
int puts(const char *s);

puts() writes the string s and a trailing newline to stdout.

int printf(const char *format, ...);

The function printf() writes output to stdout, under the control of a format string that specifies how subsequent arguments are converted for output.

I'll use this opportunity to ask you to read the documentation.

Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
10

Right, printf could be thought of as a more powerful version of puts. printf provides the ability to format variables for output using format specifiers such as %s, %d, %lf, etc...

Justin Ethier
  • 131,333
  • 52
  • 229
  • 284
8

the printf() function is used to print both strings and variables to the screen while the puts() function only permits you to print a string only to your screen.

2

puts is the simple choice and adds a new line in the end and printfwrites the output from a formatted string.

See the documentation for puts and for printf.

I would recommend to use only printf as this is more consistent than switching method, i.e if you are debbugging it is less painfull to search all printfs than puts and printf. Most times you want to output a variable in your printouts as well, so puts is mostly used in example code.

NAND
  • 663
  • 8
  • 22
Johan Engblom
  • 215
  • 1
  • 12
0

When comparing puts() and printf(), even though their memory consumption is almost the same, puts() takes more time compared to printf().

Victor Zamanian
  • 3,100
  • 24
  • 31
thil
  • 9
  • 1
  • Please add some explanation to your answer such that others can learn from it - do you have reliable sources for that claim? Or some reasons to explain this difference? – Nico Haase Jun 26 '20 at 08:17
  • I do not believe that puts() takes more time than printf(). Note that puts automatically appends a newline. – Tom Kuschel May 13 '22 at 16:21