Может ли vsnprintf вернуть отрицательное значение величины больше 1? - PullRequest
1 голос
/ 01 февраля 2012

Может ли vsnprintf() вернуть отрицательное значение величины больше 1?Если да, то при каких обстоятельствах это происходит?

Я пытался использовать %ls в качестве спецификатора формата для массива char, а также пытался скопировать размер больше, чем выделенный массив.В обоих случаях я получаю -1 в качестве возвращаемого значения.

Ответы [ 2 ]

3 голосов
/ 01 февраля 2012

Стандарт C99 гласит:

§7.19.6.12 Функция vsnprintf

#include <stdarg.h>
#include <stdio.h>
int vsprintf(char *restrict s, size_t n, const char *restrict format, va_list arg);

Описание

¶2 Функция vsnprintfэквивалентно snprintf, с заменой списка переменных аргументов на arg, который должен быть инициализирован макросом va_start (и, возможно, последующими вызовами va_arg).Функция vsnprintf не вызывает макрос va_end. 245) Если копирование происходит между перекрывающимися объектами, поведение не определено.

Возвращает

¶3 Функция vsnprintf возвращает количество символов, которое было бы записано, если бы n было достаточно большим, не считая завершающий нулевой символ, или отрицательное значение, если произошла ошибка кодирования.Таким образом, вывод с нулевым символом завершается полностью, если и только если возвращаемое значение неотрицательно и меньше чем n.

245) Как функции vfprintf, vfscanf, vprintf, vscanf, vsnprintf, vsprintf и vsscanf вызывают макрос va_arg, значение arg после возврата не определено.

И, поскольку он определен в терминах snprintf(), вот этот раздел:

§7.19.6.5 Функция snprintf

#include <stdio.h>
int snprintf(char *restrict s, size_t n, const char *restrict format, ...);

Описание

¶2 Функция snprintf эквивалентна fprintf, за исключением того, что выходные данные записываются в массив (заданный аргументом s), а не в поток.Если n равно нулю, ничего не записывается, а s может быть нулевым указателем.В противном случае выходные символы за пределами n -1st отбрасываются, а не записываются в массив, и нулевой символ записывается в конце символов, фактически записанных в массив.Если копирование происходит между объектами, которые перекрываются, поведение не определено.

Возвращает

¶3 Функция snprintf возвращает количество написанных символов, если бы n было достаточнобольшое, не считая завершающий нулевой символ, или отрицательное значение, если произошла ошибка кодирования.Таким образом, завершенный нулем вывод был полностью записан тогда и только тогда, когда возвращаемое значение неотрицательно и меньше чем n.


Он не говорит, что вернет -1на ошибку;просто любое отрицательное значение.Так что да, разрешено давать отрицательное значение с величиной больше 1 при ошибке.


Версии Microsoft

Обратите внимание, что спецификация Microsoft для vsnprintf для Visual Studio 2015 говорит:

vsnprintf возвращает количество написанных символов, не считая завершающий нулевой символ.Возвращаемое значение -1 указывает, что произошла ошибка кодирования.Если размер буфера, указанный параметром count, недостаточно велик, чтобы вместить выходные данные, заданные форматом и argptr, возвращаемое значение vsnprintf - это количество символов, которое было бы записано, если count был достаточно большим.Если возвращаемое значение больше, чем count-1, выходные данные были усечены.

Оба _vsnprintf и _vsnwprintf возвращают количество написанных символов, если количество записываемых символов меньше или равнорассчитывать;если количество записываемых символов больше, чем count, эти функции возвращают -1, указывая, что вывод был усечен.Возвращаемое значение для всех функций не включает завершающий ноль, если он записан.

Обратите внимание, что это не всегда так:

Начиная с UCRT вVisual Studio 2015 и Windows 10 vsnprintf больше не идентичны _vsnprintf.Функция vsnprintf соответствует стандарту C99;_vnsprintf сохраняется для обратной совместимости.

Для сравнения, документация Visual Studio 2013 гласит:

vsnprintf, _vsnprintf и _vsnwprintf возвращают количество написанных символов, если количество записываемых символов меньше или равно количеству;если число символов для записи больше, чем count, эти функции возвращают -1, указывая, что вывод был усечен.Возвращаемое значение не включает завершающий ноль, если он записан.

Сравнимые страницы для snprintf():

3 голосов
/ 01 февраля 2012

Да, может, как в «разрешено». Обстоятельства зависят от вашей платформы и не указываются и не регулируются каким-либо образом. Единственная переносимая вещь, которую нужно сделать с возвращаемым значением, это проверить его на < 0, чтобы увидеть, не было ли ошибки.

Из стандарта (7.21.6.12 (3), vsnprintf):

вывод с нулевым символом в конце был полностью записан тогда и только тогда, когда возвращаемое значение неотрицательно и меньше n.

Любая данная платформа может, конечно, давать дополнительные гарантии относительно возвращаемого значения; обратитесь к документации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...