abelenky
abelenky

Reputation: 64710

Is vsnprintf_s an appropriate replacement for deprecated vsnprintf?

In my code (strict C, not C++), I use vsnprintf this way:

char* buf = NULL;
size_t sz;
sz = vsnprintf( buf, 0, format, args); // Ask vsnprintf how big a buffer we need

buf = (char*) malloc(sz + 1);
vsnprintf( buf, sz, format, args); // Now actually fill the buffer
/* Use buf in a dialog box... then: */
free(buf);

But MS Visual C++ (MSVS10) compiler warns:

warning C4996: 'vsnprintf': This function or variable may be unsafe. Consider using vsnprintf_s instead. 

However, vsnprintf_s does not have the nifty feature that when you pass NULL for the buffer it will describe how much data it would have printed. Instead, it is documented to return -1.

I feel I'm using vsnprintf in a safe manner by determining the necessary size, and that the recommended replacement, vsnprintf_s isn't the same at all.

Am I missing a better / smarter way to use vsnprintf_s??

Upvotes: 7

Views: 10781

Answers (4)

EdW
EdW

Reputation: 2293

To get the buffer size you can do this:

size_t size = _vscprintf(format, argptr);

A good overview is available here vsnprintf vs vsnprintf_s . Essentially vsnprintf_s returns E_INVAL error if the buffer or format paramters are null pointers. If not null, vsnprintf_s writes up to the buffer size, truncating data that exceeds the size.

Upvotes: 0

kornman00
kornman00

Reputation: 848

I wouldn't say this is a duplicate question, as @abelenky suggests. If you want to use vsnzprintf_s in place of an old vsnprintf you need to pass _TRUNCATE (which expands to ((size_t)-1)) as the count argument (3rd parameter).

https://msdn.microsoft.com/en-us/library/d3xd30zz.aspx

If the storage required to store the data and a terminating null exceeds sizeOfBuffer, the invalid parameter handler is invoked, as described in Parameter Validation, unless count is _TRUNCATE, in which case as much of the string as will fit in buffer is written and -1 returned. If execution continues after the invalid parameter handler, these functions set buffer to an empty string, set errno to ERANGE, and return -1.

Upvotes: 0

Shahbaz
Shahbaz

Reputation: 47563

VC has finally implemented the standard vsnprintf. See the ever unreliable MSDN.

Upvotes: 2

abelenky
abelenky

Reputation: 64710

Turns out this question is pretty much an exact duplicate of:

Calculating the size of an sprintf() buffer

Summary of the answer:

Use _vscprintf to figure out how big the buffer should be, then use vsnprintf_s to actually fill it.

Upvotes: 4

Related Questions