我已经问了关于strncpy
的相同问题,但string
最终包含整个输入字符串。将字符串传递给vsnprintf
时,最后一个字符总是被砍掉:https://rextester.com/UIQMX91570
为简单起见,我还在代码中内联了上面的实时示例链接:
void bar(const char* format, va_list vlist) {
const auto buf_size = vsnprintf(nullptr, 0U, format, vlist);
string buffer(buf_size, ' ');
vsnprintf(data(buffer), buf_size, format, vlist);
cout << data(buffer) << endl;
}
void foo(const char* format, ...) {
va_list vlist;
va_start(vlist, format);
bar(format, vlist);
va_end(vlist);
}
如果我用: foo("lorem ipsum %d", 13)
我得到的输出是:
洛雷姆·伊普苏姆 1
正如我所期望的那样:lorem ipsum 13
谁能解释这种差异?当我调试时,我得到 14 buf_size
,这应该足以包含整个字符串,但它没有:(
因为手册页清楚地表明
如果输出由于此限制而被截断,则返回值是字符数(不包括尾随的"\0"),如果有足够的可用空间,该字符数将写入最终字符串。
如果检查第二次vsnprintf
调用的返回值,则会看到返回值等于大小,如手册页所示:
因此,大小或更大的返回值意味着输出是 截断。
谁能解释这种差异?
因为它们记录的行为是不同的。
strncpy()
如果在复制整个数组 src 之前达到计数,则生成的字符数组不会以 null 结尾。
但vsnprintf()
最多写 buf_size-1 个字符。生成的字符串将以空字符结尾,除非buf_size为零。
重点是我的。
要vsnprintf
的 buf_size
参数指定要写入的字符数,包括终止 NUL 字符。 返回值是生成的字符数,不包括终止 NUL 字符。
你想要
const auto buf_size = vsnprintf(nullptr, 0U, format, vlist) + 1;