There are a number of differences between the snprintf and sprintf_s functions, notably in their return values and how they handle errors.

Return Values (barring errors):

  • snprintf returns the number of characters which would have been written to the buffer if the "size" argument were ignored.

  • sprintf_s returns the number of characters actually written.

Additional Checks:

The sprintf_s function also performs checks that snprintf does not, including. The call fails (and returns zero) if any of the following are true:

  1. The %n format specifier is given.
  2. Any of the arguments corresponding to a %s format specifier are null pointers.
  3. The given "size" argument is zero.
Answer from Adrian Mole on Stack Overflow
Top answer
1 of 3
10

There are a number of differences between the snprintf and sprintf_s functions, notably in their return values and how they handle errors.

Return Values (barring errors):

  • snprintf returns the number of characters which would have been written to the buffer if the "size" argument were ignored.

  • sprintf_s returns the number of characters actually written.

Additional Checks:

The sprintf_s function also performs checks that snprintf does not, including. The call fails (and returns zero) if any of the following are true:

  1. The %n format specifier is given.
  2. Any of the arguments corresponding to a %s format specifier are null pointers.
  3. The given "size" argument is zero.
2 of 3
7

The main differences between snprintf and sprintf_s are:

  1. The function snprintf is available on all ISO C compliant platforms, whereas the function sprintf_s does not exist on most platforms. This is because compliant platforms are not required to implement Annex K of the standard and most platforms have chosen not to implement it.
  2. The function snprintf will silently truncate the string if it is too large, whereas the function sprintf_s will call the currently installed contraint handler function. However, with snprintf, it is possible to detect whether a silent truncation occurred, by inspecting the function's return value.
  3. The function sprintf_s will perform additional validation of the function arguments (such as checking for a NULL pointer) and will call the currently installed constraint handler function if these validations fail, whereas calling snprintf with an invalid argument will invoke undefined behavior (i.e. possibly crash the program).
🌐
Microsoft Learn
learn.microsoft.com › en-us › cpp › c-runtime-library › reference › sprintf-s-sprintf-s-l-swprintf-s-swprintf-s-l
sprintf_s, _sprintf_s_l, swprintf_s, _swprintf_s_l | Microsoft Learn
July 2, 2025 - If the buffer is too small for ... parameter handler is invoked. Unlike _snprintf, sprintf_s guarantees that the buffer will be null-terminated unless the buffer size is zero....
🌐
Reddit
reddit.com › r/codinghelp › sprintf() vs. snprintf()
r/CodingHelp on Reddit: sprintf() vs. snprintf()
February 23, 2023 -

Haven't written any C++ for a while and just ran into snprintf() when XCode complained that sprintf() is deprecated. snprintf() is supposed to be "safer" than sprintf. But this seems to overwrite the buffer happily:

char s[5];
snprintf(s, 64, "%s\n", "Too long for your buffer");
printf("%s", s);

It only stops after it overflows the buffer and prints the string. Then it figures out the stack has been corrupted.

Safer?

🌐
EDUCBA
educba.com › home › software development › software development tutorials › top differences tutorial › sprintf vs snprintf
sprintf vs snprintf | Top Differences of sprintf vs snprintf
March 4, 2023 - While doing concatenation, the functions are used differently in both sprintf and snprintf. For example, if we need to print ‘My name is Nelson’ in both sprintf and snprintf the method is different. ... Snprintf (buf, sizeof(buf), “%s”, “My name “); Snprintf (buf+strlen(buf), sizeof(buf)-strlen(buf), “%s”, ” is Nelson”);
Address   Unit no. 202, Jay Antariksh Bldg, Makwana Road, Marol, Andheri (East),, 400059, Mumbai
🌐
The Coding Forums
thecodingforums.com › archive › archive › c programming
snprintf and snprintf_s | C Programming | Coding Forums
April 27, 2014 - snprintf accepts a buffersize of zero and a null buffer pointer. That means that snprintf is used to just calculate the number of characters that would be required by the given format string and arguments.
🌐
Reddit
reddit.com › r/learnprogramming › is c's sprintf function actually unsafe?
r/learnprogramming on Reddit: Is C's sprintf function actually unsafe?
March 8, 2022 -

So I recently discovered that Visual Studio 2019 apparently disables the sprintf function by default and says to consider using their version, sprintf_s instead. It won't even compile code that uses it unless I specifically disable the warning.

This seems very odd since sprintf is a standard C library function and, AFAIK, using it isn't against the standard usage guidelines or best practices, unlike, e.g. using goto's. So what's up with this? If it's really unsafe, why hasn't a safer version of it already been written for the standard library? And if it's not unsafe, why is Visual Studio complaining about it?

And should I use sprintf_s instead? My concern with doing that is that I suspect other compilers wouldn't recognize it and so the code wouldn't be portable, plus Microsoft isn't really clear on the proper syntax for it.

Top answer
1 of 5
17

I found this on using _snprintf() as an alternative, and the gotchas involved if the buffer overrun protection actually triggers. From what I could see at a quick glance, similar caveats apply to sprintf_s.

Can you see the problem? In the Linux version, the output is always null-terminated. In MSVC, it's not.

Even more subtle is the difference between the size parameter in Linux and count parameter in MSVC. The former is the size of the output buffer including the terminating null and the latter is the maximum count of characters to store, which excludes the terminating null.

Oh, and don't forget to send a mail to Microsoft demanding they support current language standards. (I know they already announced they have no plan to support C99, but bugger them anyway. They deserve it.)

Bottom line, if you want to play it really safe, you'll have to provide your own snprintf() (a wrapper around _snprintf() or sprintf_s() catching their non-standard behaviour) for MSVC.

2 of 5
15

Your proposal can work if you are being careful. The problem is that both function behave slightly different, if that is not a problem for you, you are good to go, otherwise think about a wrapper function:

Differences between MSVCs _snprintf and official C99 (gcc,clang) snprintf:

Return value:

  • MSVC: return -1 if buffer size not enough to write everything (not including terminating null!)
  • GCC: return number of characters that would have been written if buffer large enough

Written bytes:

  • MSVC: write as much as possible, do not write NULL at end if no space left
  • GCC: write as much as possible, always write terminating NULL (exception: buffer_size=0)

Interesting %n subtlety: If you use %n in your code, MSVC will leave it unitialized! if it it stops parsing because buffer size is to small, GCC will always write number of bytes which would have been written if buffer would have been large enough.

So my proposal would be to write your own wrapper function mysnprintf using vsnprintf / _vsnprintf which gives same return values and writes the same bytes on both platforms (be careful: %n is more difficult to fix).

Find elsewhere
🌐
Oracle
docs.oracle.com › cd › E88353_01 › html › E37843 › sprintf-s-3c.html
sprintf_s - man pages section 3: Basic Library Functions
July 27, 2022 - The sprintf() function places output, ... that enough storage is available. The snprintf() function is identical to sprintf() with the addition of the argument n, which specifies the maximum number of bytes to write to the buffer referred to by s....
🌐
Tenasys
support.tenasys.com › 6-2 › sprintf
sprintf, sprintf_s, swprintf, swprintf_s
The other main difference between ... string and the invalid parameter handler is invoked. Unlike snprintf, sprintf_s guarantees that the buffer will be null-terminated (unless the buffer size is zero)....
🌐
DEV Community
dev.to › ashok83 › snprintf-vs-sprintf-a-deep-dive-into-buffer-overflows-prevention-59hg
Snprintf vs Sprintf: A Deep Dive into Buffer Overflows Prevention - DEV Community
May 31, 2023 - It helps secure the formatting of strings by putting a cap on the maximum number of characters allowed on the buffer. It is essentially a secure alternative to the sprintf() function. Understanding the differences between snprintf vs sprintf and their use cases are two vital points every C programmer should know.
🌐
Post.Byes
post.bytes.com › home › forum › topic
what is the difference between sprintf and snprintf? - Post.Byes
July 28, 2009 - The snprintf function returns the number of characters that should be output to the string buffer, So the return value of snprintf may be greater than the given available buffer size and the resulting string length. you should check out studytonight for futher information.
🌐
Sternum IoT
sternumiot.com › home › sprintf and snprintf c functions – syntax, examples, and security best practices
sprintf and snprintf C Functions | Syntax, Examples & Security Best Practices| Sternum IoT
June 4, 2023 - Safety: buffer overflows… Enough said. Improved error handling: With snprintf(), you can detect errors like truncation or encoding issues by checking its return value, whereas with sprintf(), there’s no direct way to determine if something went wrong during formatting.
🌐
Oracle
docs.oracle.com › cd › E88353_01 › html › E37843 › snprintf-s-3c.html
snprintf_s - man pages section 3: Basic Library Functions
The sprintf() function places output, ... that enough storage is available. The snprintf() function is identical to sprintf() with the addition of the argument n, which specifies the maximum number of bytes to write to the buffer referred to by s....
🌐
GNU
gnu.org › software › libc › manual › html_node › Formatted-Output-Functions.html
Formatted Output Functions (The GNU C Library)
The snprintf function is similar to sprintf, except that the size argument specifies the maximum number of characters to produce. The trailing null character is counted towards this limit, so you should allocate at least size characters for the string s.
🌐
Tenasys
support.tenasys.com › 7-1 › sprintf
sprintf, sprintf_s, swprintf, swprintf_s - INtime SDK - TenAsys
The other main difference between ... string and the invalid parameter handler is invoked. Unlike snprintf, sprintf_s guarantees that the buffer will be null-terminated (unless the buffer size is zero)....
🌐
Reddit
reddit.com › r/c_programming › is there an alternative to `sprintf()`
r/C_Programming on Reddit: Is There an Alternative to `sprintf()`
August 14, 2022 -

I am using the sprintf function to create file names in the form of 000.jpg. Here is a line I used:

sprintf(file_name, "%03i.jpg", images);

But my text editor warned me about sprintf:

Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]

It recommends using sprintf_s. But I do not know how to use it and I did not see tutorials for it.