2011-01-26 28 views
7

Necesito una función C que devuelva la longitud final de una cadena formateada para poder asignar correctamente la cadena objetivo, en lugar de calcular la longitud yo mismo. Hay snprintf que hace esto al no poder escribir toda la cadena, pero lamentablemente no hay una amplia alternativa de char para ella.¿Hay una versión de wchar_t para asprintf?

swprintf devuelve -1 en caso de error, no la longitud necesaria (por qué no el mismo comportamiento?!?)

El título menciona asprintf parece ser de ninguna ayuda también, ya que proporciona una amplia no solo versión

_vscwprintf puede usarse en Windows, pero necesito una plataforma cruzada, una versión estándar o, al menos, una versión de Linux y voy a #ifdef el código.

¿Alguna idea? ¡Gracias!

Respuesta

3

POSIX 2008 agregó la función open_wmemstream que, junto con vfwprintf, hace exactamente lo que necesita. Anteriormente era una extensión de GNU, por lo que ha estado disponible en sistemas GNU durante mucho tiempo.

Esto se puede utilizar fácilmente para construir un contenedor awprintf.

+1

Muchas gracias. Este truco es bueno y realmente funciona. Todavía no entiendo por qué cosas tan simples como 'awprintf' no llegan al estándar cuando se agregan características más complicadas. – gheorghe1800

+0

Probablemente porque el estándar en cuestión es POSIX y casi nadie codifica para sistemas POSIX usa 'wchar_t' excepto cuando tienen que ... –

2

Bueno, parece que hay un defecto fundamental en sus expectativas. La adición de estas arriba:

  1. Windows tiene lo que quiere
  2. Linux tiene una variante no son de ancho (asprintf no se encuentra en cualquier punto de vista, sino meramente una extensión de GNU para Linux y * BSD).
  3. POSIX define todo el archivo/cadena relacionado como una matriz char* terminada en nulo, lo que explica la falta de versiones anchas de prácticamente cualquier función POSIX.
  4. Además de 2, 3 y 4, todas las distribuciones modernas de Linux están basadas en UTF-8, lo que significa que las versiones no anchas son "lo que se debe usar".

Sumando esto da: ¿por qué necesitarías algo como esto? Seguramente no estés usando wchar_t s en Unix eres ;). Si es así, todavía hay dos opciones: cambiar a una solución similar al tchar (typedef dependiente de la plataforma) o cambiar completamente a UTF-8.

+0

Gracias por la respuesta. Sí, tengo que usar wchar_t y cambiar a UTF-8 puede ser demasiado costoso. – gheorghe1800

+0

@ gheorghe1800: deseche wchar_t y use [UTF-8] (http://utf8everywhere.org/). Si lo hubieras seguido, esta pregunta no habría surgido. – ybungalobill

3

Sí, swprintf. Tenga en cuenta que a pesar de su nombre, swprintf es el equivalente de caracteres anchos de snprintf, nosprintf, ya que toma un tamaño de búfer como su segundo parámetro; no hay (afortunadamente) ninguna versión de caracteres anchos que no tome un tamaño de búfer.

Además, dado que devuelve -1 en desbordamiento, tendrá que obtener la longitud total de la cadena de alguna otra manera. La única forma realmente portátil de hacerlo es comenzar con un búfer de cierto tamaño, intente formatear y ver si es lo suficientemente grande, y si no, aumente el tamaño y vuelva a formatear hasta que sea lo suficientemente grande. Esto no es muy eficiente, como te puedes imaginar.

+0

Gracias. Esto es lo que había pensado en primer lugar, solo esperaba que hubiera una mejor solución ya implementada.Finalmente, creo que tendré que calcular la longitud yo mismo, lo que parece propenso a errores en el caso general, pero me aseguraré de ser minucioso. – gheorghe1800

+0

Hay una mejor manera; ver mi respuesta Es posible que desee recurrir a la solución de Adam para los sistemas anteriores a POSIX-2008. –

Cuestiones relacionadas