为什么 vsnprintf 没有像 strncpy 那样写入相同数量的字符



我已经问了关于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为零。

重点是我的。

vsnprintfbuf_size 参数指定要写入的字符数,包括终止 NUL 字符。 返回值是生成的字符数,不包括终止 NUL 字符。

你想要

const auto buf_size = vsnprintf(nullptr, 0U, format, vlist) + 1;

相关内容

  • 没有找到相关文章

最新更新