Получение длины отформатированной строки из wsprintf - PullRequest
1 голос
/ 26 мая 2011

При использовании стандартных строк char* функции snprintf и vsnprintf будут возвращать длину выходной строки, даже если эта строка была усечена из-за переполнения. * Похоже, что комитет ISO C этого не сделалнравится эта функциональность, когда они добавляют swprintf и vswprintf, которые возвращают -1 при переполнении.

Кто-нибудь знает о функции, которая обеспечит эту длину?Я не знаю размер потенциальных строк.Я мог бы просить слишком много, но .. Я бы не хотел:

  • выделять огромный статический временный буфер
  • итеративно выделять и освобождать память, пока я не нашел размер, который подходит
  • добавить дополнительную библиотечную зависимость
  • написать собственный синтаксический анализатор строк формата

* Я понимаю, что MSVC этого не делает, и вместо этого предоставляет функции scprintf и vscprintf, но я 'ищу другие компиляторы, в основном GCC.

Ответы [ 2 ]

2 голосов
/ 26 мая 2011

Мое лучшее предложение для вас - вообще не использовать строки wchar_t, особенно если вы не пишете Windows-ориентированный код.В случае, если это не вариант, вот некоторые другие идеи:

  1. Если ваша строка формата сама не содержит не-ASCII символов, как насчет первого вызова vsnprintf с тем же наборомаргументы для получения длины в байтах, затем используйте ее как безопасную верхнюю границу для длины в wchar_t символах (если символов мало или не ASCII, граница будет жесткой).

  2. Если вы в порядке с введением зависимости от функции POSIX (которая, вероятно, будет добавлена ​​в C1x), используйте open_wmemstream и fwprintf.

  3. Простоитерируйте выделение больших буферов, но делайте это умно: увеличивайте размер геометрически на каждом шаге, например, 127, 255, 511, 1023, 2047, ... Мне нравится этот шаблон лучше, чем целые степени 2, потому что легко избежать опасного случая, когдавыделение может быть успешным для SIZE_MAX / 2 + 1, но затем на следующей итерации будет перенесено в 0.

0 голосов
/ 19 октября 2012

Возвращает размер буфера для строк широких символов:

vswprintf(nullptr, -1, aFormat, argPtr);
...