1

可以vsnprintf()返回幅度大于 1 的负值吗?如果是这样,它在什么情况下这样做?

我尝试将其%ls用作 char 数组的格式说明符,并尝试复制比分配的数组更大的内容。在这两种情况下,我都得到 -1 作为返回值。

4

2 回答 2

3

是的,它可以,就像“它被允许”一样。具体情况取决于您的平台,并且没有以任何方式指定或监管。与返回值有关的唯一可移植的事情是检查它< 0是否有错误。

从标准(7.21.6.12(3),vsnprintf):

当且仅当返回值为非负且小于n

当然,任何给定的平台都可以对返回值做出额外的保证;查阅您的文档。

于 2012-02-01T07:00:14.710 回答
3

C99 标准说:

§7.19.6.12vsnprintf功能

#include <stdarg.h>
#include <stdio.h>
int vsprintf(char *restrict s, size_t n, const char *restrict format, va_list arg);

描述

¶2 该vsnprintf函数等效于snprintf,变量参数列表由 替换arg,它应该已由va_start宏初始化(可能还有后续va_arg调用)。该vsnprintf函数不调用 va_end宏。245)如果复制发生在重叠的对象之间,则行为未定义。

退货

¶3 该vsnprintf函数返回已经写入n足够大的字符数,不计算终止的空字符,或者如果发生编码错误,则返回负值。因此,当且仅当返回值为非负且小于 时,以空值结尾的输出已被完全写入n

245)由于函数vfprintf, vfscanf, vprintf, vscanf, vsnprintf, vsprintf, 和 vsscanf调用va_arg宏,arg返回后的值是不确定的。

而且,由于它是根据 定义的,所以这是snprintf()该部分:

§7.19.6.5snprintf功能

#include <stdio.h>
int snprintf(char *restrict s, size_t n, const char *restrict format, ...);

描述

¶2 该snprintf函数等价于fprintf,除了输出写入数组(由参数 指定s)而不是流。如果n为零,则不写入任何内容,并且s可能是空指针。否则,第 -1 个以外的输出字符将n被丢弃而不是写入数组,并且在实际写入数组的字符的末尾写入一个空字符。如果复制发生在重叠的对象之间,则行为未定义。

退货

¶3 该snprintf函数返回已经写入n足够大的字符数,不计算终止的空字符,或者如果发生编码错误,则返回负值。因此,当且仅当返回值为非负且小于 时,以空值结尾的输出已被完全写入n


它并没有说它会-1在错误时返回。只是任何负值。所以是的,允许在误差上给出一个幅度大于 1 的负值。


微软的版本

请注意,Microsoft 的vsnprintfVisual Studio 2015 规范说:

vsnprintf返回写入的字符数,不包括终止的空字符。返回值 -1 表示发生了编码错误。如果由 count 指定的缓冲区大小不足以包含由 format 和 argptr 指定的输出,则 vsnprintf 的返回值是在 count 足够大的情况下将写入的字符数。如果返回值大于 count - 1,则输出已被截断。

如果要写入的字符数小于或等于 count,则返回和返回写入的字符数_vsnprintf_vsnwprintf如果要写入的字符数大于 count,则这些函数返回 -1,表示输出已被截断。所有函数的返回值都不包括终止的 null,如果写入了一个。

请注意,情况并非总是如此:

从 Visual Studio 2015 和 Windows 10 中的 UCRT 开始,vsnprintf不再与_vsnprintf. vsnprintf功能符合C99标准;_vnsprintf为向后兼容而保留。

为了比较,Visual Studio 2013文档说:

vsnprintf, _vsnprintf,_vsnwprintf如果要写入的字符数小于或等于 count,则返回写入的字符数;如果要写入的字符数大于 count,则这些函数返回 -1,表示输出已被截断。如果写入了一个,则返回值不包括终止的空值。

可比较的页面snprintf()是:

于 2012-02-01T07:36:32.020 回答