gcc Linux上的vsnwprintf替代方案

nfeuvbwi  于 2022-11-24  发布在  Linux
关注(0)|答案(7)|浏览(237)

在linux机器上,vsnwprintf函数的直接替代方法是什么?使用它应该包含什么头文件?
多谢指教

nkcskrwz

nkcskrwz1#

这取决于vsnwprintf()(sic) 的功能及其参数列表。
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.

pqwbnv8z

pqwbnv8z2#

此函数的Linux变体是snprintfvsnprintf,它们由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);

wchar.h提供的Unicode版本:

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

xggvc2p6

xggvc2p63#

没有别的选择。
在其他答案中建议的vswprintf并没有给出所需的缓冲区长度。当你将nullptr和0传递给前两个参数时,它将返回-1,而不是所需的缓冲区长度。这既是documented的工作原理,也是它在clang 4中的实际工作原理。
在这个答案中有一个解决方法https://stackoverflow.com/a/16352146/126995滚动到vscwprintf源代码的结尾。这个解决方法适用于小字符串,但是对于较大的字符串来说相对较慢,对于非常大的字符串甚至会耗尽堆栈空间。

vecaoik1

vecaoik14#

看起来libicu中的u_vsnprintf()或u_vsnprintf_u()是您需要的

iqih9akk

iqih9akk5#

vswprintf()的截断版本是不安全的。您确实需要C11 vswprintf_s(),它可以确保空分隔的宽字符串,并在目标缓冲区太小时出错。
如您所知,wide变体没有API来计算空缓冲区的大小。如果缓冲区太小,您需要在出错时扩展缓冲区。
无论如何,safeclib-3.0都将提供所有这些选项。safe和unsafe with --enable-unsafe、宽或非宽、截断('n')或不截断。https://github.com/rurban/safeclib/blob/wchar/src/wchar/vsnwprintf_s.c
vsnwprintf在C99,MSVC和其他几个中。不在musl中。-stc=c99对glibc应该足够了。

yizd12fk

yizd12fk6#

下面是一个解决方法示例:

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;
  };

也许,它需要以某种方式限制迭代的次数。

j8ag8udp

j8ag8udp7#

对于C++,可以使用<fmt/printf.h>中libfmt的fmt::sprintf

相关问题