gpt4 book ai didi

c++ - 如何在 C++03 中用 sprintf 正确替换 sprintf_s?

转载 作者:行者123 更新时间:2023-11-30 03:18:54 30 4
gpt4 key购买 nike

sprintf_s 是函数 sprintf 的 Microsoft 实现,他们修补了一个缺陷,添加了一个参数以获取函数被限制写入的边界值。

C++11 中引入了一个等价物:snprintf。但在这里,我们谈论的是 C++03 语法。

签名:

count_char_written sprintf(char* string_out, const char* output_template, VARIADIC_ARGS);
// and
count_char_written sprintf_s(char* string_out, size_t buffer_max_size, const char* output_template, VARIADIC_ARGS);

在功能上,sprintf_ssprintf 更高级,因为它避免了溢出。但是 sprintf_s 仅适用于 Microsoft!

如果您想将使用 sprintf_s 编写的 C++03 代码移植回 POSIX 兼容语法,该怎么办?

最佳答案

今天,snprintfvsnprintf 应该随处可用,但 MSVC12 及更早版本的 Windows 除外。最简单的方法是在 Windows 上提供 snprintf/vsnprintf(如果它不可用)。

Windows 提供了函数 _vsnprintf_s ,它已经与 vsnprintf 类似,但在提供的缓冲区太小时发生的情况有以下重要差异:

  • 缓冲区内容取决于 vsnprintf 中不存在的附加 count 参数。要获得 vsnprintf 行为,您可以在此处传递 _TRUNCATE
  • 返回
  • -1 而不是所需的字符数。这可以通过使用 _vscprintf 函数来解决,该函数只需要在之前调用 _vsnprintf_s 失败时调用。

此外,这些函数不支持 C99 中添加的格式说明符,例如 %zd。这不容易解决,您必须避免使用它们。

代码如下:

int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
{
int r = -1;

if (size != 0)
{
va_list args_copy;
va_copy(args_copy, args);
r = _vsnprintf_s(buf, size, _TRUNCATE, fmt, args_copy);
va_end(args_copy);
}

if (r == -1)
{
r = _vscprintf(fmt, args);
}

return r;
}

int snprintf(char *buf, size_t size, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
int r = vsnprintf(buf, size, fmt, args);
va_end(args);
return r;
}

注意:Windows 还提供了 _vsnprintf,它看起来更适合此实现,但它不会终止结果字符串。如果你想使用它,你应该小心。

关于c++ - 如何在 C++03 中用 sprintf 正确替换 sprintf_s?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54238576/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com