What are the differences between printf, fprintf, sprintf, snprintf, printf_s and fprintf_s?

Asked

Viewed 9,114 times

6

Researching I noticed that there are several variations of printf, but I did not understand which differences and which to use in a certain circumstance.

I would like to know the purpose of each with their differences and how they can be used.

3 answers

6


All are defined in <stdio.h>:

int printf( const char *format, ... );                                                 <C99
int printf( const char *restrict format, ... );                                         C99+

printf writes in the stream outgoing stdout.

int fprintf( FILE *stream, const char *format, ... );                                  <C99
int fprintf( FILE *restrict stream, const char *restrict format, ... );                 C99+

fprintf writes in a stream output defined by stream.

int sprintf( char *buffer, const char *format, ... );                                  <C99
int sprintf( char *restrict buffer, const char *restrict format, ... );                 C99+

sprintf writes to a character buffer defined by buffer. The behavior is undefined if the string and its terminator are larger than the array pointed.

int snprintf( char *restrict buffer, int bufsz, const char *restrict format, ... );     C99+

snprintf writes to string buffer, up to the maximum of bufsz - 1, ending with null unless bufsz is zero. If it is zero, nothing is written down, but the number of bytes which would be written is calculated and returned anyway. In this specific case, buffer can be null pointer

int printf_s( const char *restrict format, ...);                                        C11+
int fprintf_s( FILE *restrict stream, const char *restrict format, ...);                C11+
int sprintf_s( char *restrict buffer, rsize_t bufsz, const char *restrict format, ...); C11+
int snprintf_s( char *restrict buffer, rsize_t bufsz, const char *restrict format, ...);C11+

These functions suffixed by _s are equivalent to the first four, but the following errors are detected in these versions, and call the Handler of Constraint installed:

  • the specifier %n is present in the format
  • any argument corresponding to a %s is null pointer
  • format or buffer is null pointer
  • bufsz is zero or greater than RSIZE_MAX
  • character conversion errors
  • (only to sprintf_s) string with terminator is larger than bufsz


Note: the availability of fprintf_s, sprintf_s, and snprintf_s is only guaranteed if the implementation __STDC_LIB_EXT1__ and the user define __STDC_WANT_LIB_EXT1__ as 1 before including <stdio.h>.


Reference:

http://en.cppreference.com/w/c/io/fprintf

3

printf (print Formatted) writes a formatted text to the standard output stream (stdout).

fprintf (file print Formatted) writes a formatted text to an output stream that the user specifies.

sprintf (print string Formatted) writes a text formatted for a string.

snprintf (safe sprintf) the same as the sprintf, but is not susceptible to buffer overflow.

Logically, printf_s and fprintf_s would be the safe versions of printfand fprintf, respectively, i.e., versions where there is verification of the accessed memory positions, so that there is no buffer overflow or improper access to another memory position. However, I admit, I’ve never used/never seen these functions.

You can find good examples in the documentation. Example: printf. In the search, change the function name and you will see definition, parameters, return type, examples and more.

I hope it helped!

1

Everyone’s operation is similar, so I don’t see the need for examples. I assume you know how to use printf(). All use the convention of a "mask" string followed by a vararg, i.e., a variable number of arguments that meet the % present in the mask. The functions you quoted differ basically in what happens with the result string.

printf: prints the result in stdout (standard output, which in the case of command line execution is the terminal).

fprintf: sends the result to the opened file passed as the first parameter (type FILE).

sprintf: sends the result to a buffer, passed as the first parameter. This function is considered insecure because the result may be greater than this buffer, especially if the vararg parameters are provided by an external agent, opening the door to an invasion (stack overflow).

snprintf: secure version of sprintf. The second parameter passed is the size of the buffer passed in the first parameter. If the result is larger than the declared buffer size, it will be filled to the limit, but without stack overflow.

asprintf: secure version of sprintf which is only offered on GNU systems (e.g. Linux). The result is returned as a dynamically allocated string, in the required size. It is better than snprintf because it is not necessary to calculate the largest possible result size.

printf_s, sprintf_s, etc: idem versions without suffix _s, but some additional checks are done in order to avoid the typical bugs when using the family printf:

1) seal the mask %n, source of a whole class of bugs and attacks

2) checks whether any of the parameters corresponding to %s is null

3) checks whether format or buffer is NULL

4) checks that the buffer size is valid

5) the function sprintf_s requires the buffer size as the second parameter, and the result is only stored in the buffer if it fits, other than snprintf(_s) that stores the part of the result that fits.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.