Есть ли версия wchar_t для asprintf? - PullRequest
7 голосов
/ 26 января 2011

Мне нужна функция C, которая возвращает окончательную длину отформатированной строки, чтобы я мог правильно распределить целевую строку, а не вычислять длину самостоятельно. Существует snprintf, который делает это только при невозможности написать всю строку, но, к сожалению, для него нет широкой альтернативы char.

swprintf возвращает -1 в случае ошибки, а не необходимую длину (почему не то же самое поведение?!?)

Упомянутое название asprintf, похоже, также не поможет, так как предоставляет только неширокую версию.

_vscwprintf можно использовать в Windows, но мне нужна кроссплатформенная, стандартная версия или хотя бы версия Linux, и я #ifdef для кода.

Есть идеи? Спасибо!

Ответы [ 3 ]

3 голосов
/ 26 января 2011

Да, swprintf.Обратите внимание, что, несмотря на название, swprintf является эквивалентом snprintf, , а не sprintf в широком символе, поскольку в качестве второго параметра он принимает размер буфера;(к счастью) нет версии с широкими символами, которая не принимает размер буфера.

Кроме того, поскольку при переполнении она возвращает -1, вам придется получить общую длину строки другим способом.Единственный действительно переносимый способ сделать это - начать с буфера некоторого размера, попробовать форматирование и посмотреть, достаточно ли он велик, а если нет, увеличить размер и переформатировать, пока он не станет достаточно большим.Это не очень эффективно, как вы можете себе представить.

3 голосов
/ 27 января 2011

POSIX 2008 добавил функцию open_wmemstream, которая вместе с vfwprintf делает именно то, что вам нужно. Ранее это было расширение GNU, поэтому оно долгое время было доступно в системах GNU.

Это можно легко использовать для создания оболочки awprintf.

2 голосов
/ 26 января 2011

Ну, кажется, в ваших ожиданиях есть фундаментальный недостаток.Добавим следующее:

  1. В Windows есть то, что вы хотите
  2. В Linux есть неширокий вариант (asprintf не входит ни в какой стандарт, но является просто расширением GNU для Linux и *BSD).
  3. POSIX определяет все строки / файлы, относящиеся к массиву char* с нулевым символом в конце, что объясняет отсутствие широких версий почти любой функции POSIX.
  4. В верхней части, 3 и 4, все современные дистрибутивы Linux основаны на UTF-8, что означает, что «широкие версии - это то, что« предназначено для использования ».

Добавление этих ссылок дает: зачем вамчто-то вроде этого?Конечно, вы не используете wchar_t s в Unix, если вы ;).Если да, есть еще два варианта: переключиться на tchar -подобное решение (зависящее от платформы typedef) или полностью переключиться на UTF-8.

...