What is the direct alternative for the vsnwprintf
function on linux machines and what headers should be included to use it?
Thanks for any advice
Linux variant of this function is snprintf
and vsnprintf
which are kindly provided by stdio.h
:
int snprintf(char *str, size_t size, const char *format, ...);
int vsnprintf(char *str, size_t size, const char *format, va_list args);
and Unicode versions provided by wchar.h
:
int swprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, ...);
int vswprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, va_list args);
http://linux.die.net/man/3/snprintf
http://linux.die.net/man/3/swprintf
It depends on what vsnwprintf()
(sic) does and what is its parameter list.
The C99 Standard describes vswprintf()
(in section 7.24.2.7). To use it you need to #include <stdarg.h>
and <wchar.h>
. The implementation should be in the Standard library.
There’s no alternative for that.
vswprintf suggested in other answers doesn’t tell required buffer length. When you’ll pass nullptr and 0 to the first two arguments, it will returns -1, not the required buffer length. This is both how it's documented, and how it works in practice in clang 4.
There’s a workaround in that answer https://stackoverflow.com/a/16352146/126995 Scroll to the end of that for vscwprintf source code. The workaround works for small strings, but relatively slow for larger strings, and can even exhaust stack space for a very large string.
The truncating version of vswprintf()
is unsafe.
You really want the C11 vswprintf_s()
, which ensures a null delimited wide string, and errors when the destination buffer is too small.
As you know, the wide variants have no API to calculate the size with a NULL buffer. You need to extend the buffer on errors, if the buffer is too small.
Anyway, safeclib-3.0 will provide all of them. safe and unsafe with --enable-unsafe, wide or non-wide, truncating ('n') or not-truncating. https://github.com/rurban/safeclib/blob/wchar/src/wchar/vsnwprintf_s.c
vsnwprintf
is in C99, MSVC, and a few others. Not in musl.
-stc=c99
should be enough for glibc.
Here an example of workaround:
int vsnwprintf(wchar_t* buffer, size_t size, const wchar_t* format, va_list& params)
{
if(buffer || size)
return vswprintf(buffer, size, format, params);
int result = -1;
for(size = 100; result < 0; size += 100)
{
unique_ptr<wchar_t[]> guard(buffer = new wchar_t[size]);
va_list copy;
va_copy(copy, params);
result = vswprintf(buffer, size, format, copy);
va_end(copy);
}
return result;
};
Probably, it's needed to limit a number of iterations in some way.