sprintf против wsprintf в VS2017 с "%. * s" - PullRequest
0 голосов
/ 15 апреля 2019

При попытке вывести некоторые подсчитанные строки я обнаружил следующую асимметрию между функциями Microsoft sprintf() и wsprintf():

#define _UNICODE

sprintf(buff, "%.3s", "abcdef");  //Outputs: "abc"
sprintf(buff, "%.*s", 3, "abcdef");  //Outputs: "abc"

wsprintf(buff, L"%.3s", L"abcdef");  //Outputs: L"abc"
wsprintf(buff, L"%.*s", 3, L"abcdef");  //Outputs: L"*s"

Обратите внимание, что последний wsprintf() не выводит L"abc", как его узкая сестринская функция sprintf() с такими же (но широкими) аргументами.

Q : это ошибка или функция?

Примечание : Это похоже на проблему, описанную здесь: Различия в форматировании между sprintf () и wsprintf () в VS2015

1 Ответ

1 голос
/ 15 апреля 2019

wsprintf старый, очень старый.Он не документирует * в точности, поэтому не передавайте эту строку формата в wsprintf.Ваш тест технически не указан.

Обратите внимание, что wsprintf не будет записывать более 1023 символов в buff с последующим нулевым символом и в UCS-2, а не в UTF-16.Конструкция этой функции заключается в том, что вы передаете ей буфер стека фиксированного размера, равный 1024, и не беспокоитесь о переполнении буфера, поскольку она усекается для вас.

Насколько я могу судить по ее намерению, она больше предназначена для созданияотладочные сообщения для передачи на MessageBox, а не для фактического использования приложения.Это очень сокращенная форма snprintf с фиксированной n, которая реализована независимо от других стандартных библиотек.

Хорошо, поэтому вы хотите, чтобы swprintf всегда заканчивался нулем.Попробуйте это:

int swprintf2(wchar_t *ws, size_t len, const wchar_t* format, ...)
{
    va_arg arg;
    va_start(arg, format);
    ws[len - 1] = 0;
    return vswprintf(ws, len - 1, format, arg);
}
...