'vsnwprintf alternative on linux

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



Solution 1:[1]

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

Solution 2:[2]

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.

Solution 3:[3]

Seems that u_vsnprintf() or u_vsnprintf_u() from libicu is what you need

Solution 4:[4]

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.

Solution 5:[5]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Soonts
Solution 3 ????????? ??????
Solution 4 rurban
Solution 5 Serge Roussak