Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

snprintf and Visual Studio 2010

I'm unfortunate enough to be stuck using VS 2010 for a project, and noticed the following code still doesn't build using the non-standards compliant compiler:

#include <stdio.h> #include <stdlib.h>  int main (void) {     char buffer[512];      snprintf(buffer, sizeof(buffer), "SomeString");      return 0; } 

(fails compilation with the error: C3861: 'snprintf': identifier not found)

I remember this being the case way back with VS 2005 and am shocked to see it still hasn't been fixed.

Does any one know if Microsoft has any plans to move their standard C libraries into the year 2010?

like image 654
Andrew Avatar asked May 26 '10 18:05

Andrew


People also ask

What is the difference between Sprintf and Snprintf?

The snprintf() function is identical to the sprintf() function with the addition of the n argument, which indicates the maximum number of characters (including the ending null character) to be written to buffer.

What is Snprintf in C?

The snprintf() function formats and stores a series of characters and values in the array buffer. The snprintf() function accepts an argument 'n', which indicates the maximum number of characters (including at the end of null character) to be written to buffer.

Does snprintf null terminate the string?

snprintf ... Writes the results to a character string buffer. (...) will be terminated with a null character, unless buf_size is zero. So all you have to take care is that you don't pass an zero-size buffer to it, because (obviously) it cannot write a zero to "nowhere".


2 Answers

Short story: Microsoft has finally implemented snprintf in Visual Studio 2015. On earlier versions you can simulate it as below.


Long version:

Here is the expected behavior for snprintf:

int snprintf( char* buffer, std::size_t buf_size, const char* format, ... ); 

Writes at most buf_size - 1 characters to a buffer. The resulting character string will be terminated with a null character, unless buf_size is zero. If buf_size is zero, nothing is written and buffer may be a null pointer. The return value is the number of characters that would have been written assuming unlimited buf_size, not counting the terminating null character.

Releases prior to Visual Studio 2015 didn't have a conformant implementation. There are instead non-standard extensions such as _snprintf() (which doesn't write null-terminator on overflow) and _snprintf_s() (which can enforce null-termination, but returns -1 on overflow instead of the number of characters that would have been written).

Suggested fallback for VS 2005 and up:

#if defined(_MSC_VER) && _MSC_VER < 1900  #define snprintf c99_snprintf #define vsnprintf c99_vsnprintf  __inline int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) {     int count = -1;      if (size != 0)         count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);     if (count == -1)         count = _vscprintf(format, ap);      return count; }  __inline int c99_snprintf(char *outBuf, size_t size, const char *format, ...) {     int count;     va_list ap;      va_start(ap, format);     count = c99_vsnprintf(outBuf, size, format, ap);     va_end(ap);      return count; }  #endif 
like image 191
Valentin Milea Avatar answered Sep 22 '22 13:09

Valentin Milea


snprintf is not part of C89. It's standard only in C99. Microsoft has no plan supporting C99.

(But it's also standard in C++0x...!)

See other answers below for a workaround.

like image 32
kennytm Avatar answered Sep 19 '22 13:09

kennytm