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

╄→гoц情女王★ 提交于 2019-12-14 03:23:55

问题


I've asked the same question about strncpy, 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

For simplicity I've also included the live example link above inline in the code:

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

    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);
}

If I call this with: foo("lorem ipsum %d", 13) the output I get is:

lorem ipsum 1

Where as I would have expected: lorem ipsum 13

Can anyone explain the discrepancy? When I debug I get a buf_size of 14 which should be enough to contain the entire string, yet it does not :(


回答1:


Can anyone explain the discrepancy?

Because their documented behavior is different.

strncpy()

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

but 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.

emphasis is mine.




回答2:


Because man page clearly says that

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

If you'd check the return value of your second vsnprintf call, you'd see that return value is equal to the size, as in the man page:

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




回答3:


The buf_size parameter to vsnprintf specifies how many characters to write, including the terminating NUL character. The return value is the number of characters produced, not including the terminating NUL character.

You want

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


来源:https://stackoverflow.com/questions/54135026/why-is-vsnprintf-not-writing-the-same-number-of-characters-as-strncpy-would

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!