tl; dr: По той или иной причине эта семантика нулевого завершения зависит от успешного вызова функции, а для swprintf
она успешна только в том случае, если буфер достаточно большой.Следовательно, массив в вашей первой попытке не заканчивается нулем.
Это тонкий, но swprintf
не похож на snprintf
.Он не пишет «не более N-1 символов» и считает его успешным во всех случаях.
Вот что говорится в той же документации о возвращаемом значении swprintf
:
Возвращаемое значение: Количество написанных широких символов (не считая завершающих нулевых широких символов), если успешно или отрицательное значение, если произошла ошибка кодирования или если число генерируемых символов было равно или больше размера (включая, когда размер равен нулю)
И, действительно, Ваша попытка возвращает -1 .
Из этого (и из примечания под этой цитатой) мы можемубедитесь, что swprintf
считает операцию сбой , если в предоставленном выходном буфере недостаточно байт.Он не будет переполнять этот буфер, но он также может не завершить свою работу, и его работа включает в себя написание терминатора NULL.Без этого NULL-терминатора wchar_t*
, который вы [эффективно] передаете на std::wcout
, выйдет за пределы, и ваша программа будет иметь неопределенное поведение.
Я допускаю, что это при случайном чтенииможет показаться противоречащим семантике, окружающей параметр size
, для которого C11 сообщает:
записывается не более n
широких символов, включая завершающий нулевой широкий символ, который всегда добавляется(если n
не равен нулю).
… без указания каких-либо условий того, был ли вызов функции в противном случае успешным.
Может существовать область для вызова этого редакционного дефекта встандарт, или ошибка реализации. Но , даже если ни один из них не был истинным, ваш вызов функции был признан неудачным, и я не думаю, что вы должны полагаться на результат соответствующим образом.
Мы можем по крайней мере увидеть, что libc намерение соответствует приведенному выше сокращению, начиная с этой страницы руководства по функциям форматированного вывода :
Возвращаемое значение - это количество символов, сгенерированных для данного ввода,исключая завершающий ноль.Если не все выходные данные помещаются в предоставленный буфер, возвращается отрицательное значение.Вы должны попробовать еще раз с большей выходной строкой.Примечание: это отличается от того, как snprintf справляется с этой ситуацией.
Вам нужно учесть вышеупомянутое примечание:
В то время как узкие строки предоставляют стандартное:: snprintf, который позволяет определить требуемый размер выходного буфера, нет эквивалента для широких строк, и для определения размера буфера программе может потребоваться вызвать std :: swprintf, проверить значение результата иперераспределить больший буфер, повторить попытку до успешного завершения.
… или вообще переключиться на другие функции.