2011-01-26 2 views
7

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

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

Названные упоминаются asprintf, кажется, не помогают также, поскольку она обеспечивает не широкоформатную версия только.

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

Любые идеи? Благодаря!

ответ

3

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

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

+1

Большое спасибо. Этот хак хорош, и он действительно работает. Я все еще не понимаю, почему такие простые вещи, как 'awprintf', не доходят до стандарта, когда добавляются более сложные функции. – gheorghe1800

+0

Наверное, потому, что стандартом является POSIX, и почти никто не кодирует системы POSIX, использует 'wchar_t', за исключением случаев, когда они ... –

2

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

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

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

+0

Спасибо за ответ. Да, мне нужно использовать wchar_t, и переключение на UTF-8 может быть слишком дорогостоящим. – gheorghe1800

+0

@ gheorghe1800: scrap wchar_t и использовать [UTF-8] (http://utf8everywhere.org/). Если бы вы следовали за ним, этот вопрос не возник бы. – ybungalobill

3

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

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

+0

Спасибо. Это то, о чем я думал, во-первых, я просто надеялся, что уже есть лучшее решение.Наконец, я думаю, что мне придется самому вычислить длину, которая, по всей видимости, подвержена ошибкам в общем случае, но я обязательно сделаю все возможное. – gheorghe1800

+0

Существует лучший способ; см. мой ответ. Возможно, вы захотите вернуться к решению Адама для систем pre-POSIX-2008. –

Смежные вопросы