为什么 vsnprintf 没有写出与 strncpy 相同数量的字符?

Why is vsnprintf Not Writing the Same Number of Characters as strncpy Would?

我问过, but there the string ends up containing the whole input string. When passing a string to vsnprintf the last character always gets chopped off: https://rextester.com/UIQMX91570

为简单起见,我还在代码中内联了上面的实例 link:

void bar(const char* format, va_list vlist) {
    const auto buf_size = vsnprintf(nullptr, 0U, format, vlist);
    string buffer(buf_size, '[=10=]');

    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) 我得到的输出是:

lorem ipsum 1

如我所料:lorem ipsum 13

任何人都可以解释差异吗?当我调试时,我得到一个 buf_size 的 14,其中 应该 足以包含整个字符串,但它不 :(

因为手册页清楚地说明了这一点

If the output was truncated due to this limit then the return value is the number of characters (not including the trailing '[=11=]') which would have been written to the final string if enough space had been available.

如果您检查第二个 vsnprintf 调用的 return 值,您会看到 return 值等于大小,如手册页所示:

Thus, a return value of size or more means that the output was truncated.

vsnprintfbuf_size 参数指定要写入多少个字符,包括 终止 NUL 字符 . return 值是生成的字符数,不包括 终止 NUL 字符

你想要

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

Can anyone explain the discrepancy?

因为他们记录的行为不同。

strncpy()

If count is reached before the entire array src was copied, the resulting character array is not null-terminated.

但是vsnprintf()

At most buf_size-1 characters are written. The resulting character string will be terminated with a null character, unless buf_size is zero.

重点是我的。