2012-04-03 10 views
5

Tengo un proyecto multiplataforma que se compila muy bien en mac, pero en Windows todas mis llamadas swprintf con% s están buscando wchar_t en lugar de el char * im pasándolo. Resulta que M $ pensó que sería gracioso hacer que% s significara algo diferente a char * en funciones de caracteres anchos ... http://msdn.microsoft.com/en-us/library/hf4y5e3w.aspxvisual studio swprintf está haciendo que todos mis formateadores% s quieran wchar_t * en lugar de char *

De todos modos estoy buscando un truco de codificación creativa que sea mejor que poner ifdef else termina alrededor cada llamada de cadena ancha

Respuesta

4

Visual Studio 14 CTP1 y más adelante siempre tratarán %s como una cadena estrecha (char*) a menos que defina _CRT_STDIO_LEGACY_WIDE_SPECIFIERS. También agregó la extensión de modificador de longitud T que se asigna a lo que MS llama el ancho "natural". Para sprintf%Ts es char* y para swprintf%Ts es wchar_t*.


En Visual Studio 13 y anteriores %s/%c se asigna a la anchura natural de la cadena de la función/formato y %S/%C se asigna al contrario de lo natural con:

printf("%c %C %s %S\n", 'a', L'B', "cd", L"EF"); 
wprintf(L"%c %C %s %S\n", L'a', 'B', L"cd", "EF"); 

Usted también puede forzar un ancho específico mediante el uso de un modificador de longitud: %ls, %lc, %ws y %wc siempre significa wchar_t y %hs y %hc son un siempre char. (Documentado para VS2003 y here VC6 here (No estoy seguro de %ws y cuando fue realmente original))

Mapeo %s a la anchura natural de la función fue muy útil en los días de Win9x vs. WinNT, mediante el uso de la tchar.h header puede crear versiones angostas y amplias desde la misma fuente. Cuando _UNICODE se define las funciones en tchar.h mapa para las amplias funciones y TCHAR es wchar_t, de lo contrario se utilizan las funciones estrechas y TCHAR es char:

_tprintf(_T("%c %s\n"), _T('a'), _T("Bcd")); 

hay una convención similar utilizado por los archivos y la cabecera del SDK de Windows algunas funciones de formato que existen allí (wsprintf, wvsprintf, wnsprintf y wvnsprintf) pero están controladas por UNICODE y TEXT y no _UNICODE y _T/_TEXT.

es probable que tenga 3 opciones para hacer funcionar un proyecto multiplataforma en Windows si desea apoyar más viejos compiladores de Windows:

1) los datos como un proyecto de cadena angosta en Windows, probablemente no es una buena idea y en su caso swprintf todavía tratará a% s como wchar_t *.

2) Use definiciones personalizadas similares a cómo inttypes.cadenas de formato h funcionan:

#ifdef _WIN32 
#define PRIs "s" 
#define WPRIs L"hs" 
#else 
#define PRIs "s" 
#define WPRIs L"s" 
#endif 
printf("%" PRIs " World\n", "Hello"); 
wprintf(L"%" WPRIs L" World\n", "Hello"); 

3) crear su propia versión personalizada de swprintf y utilizarlo con Visual Studio 13 y anteriores.

+0

No estoy realmente seguro de cómo usar esto, en mis pruebas cuando _UNICODE está definido o no está definido, el comportamiento es el mismo swprintf% s espera un wchar_t y no un char *. En cuanto a las extensiones de MS, ¿sabe si hay alguna forma de que gcc las use? – Medran

+0

¿Está seguro de que su entorno no lo está definiendo por usted (en la configuración del proyecto en VS)? Si por gcc quiere decir MinGW, entonces sí, MinGW puede usar el tiempo de ejecución de MS C, consulte http://stackoverflow.com/questions/6729013/mingw-printf-size-specification-character-h – Anders

+0

sin gcc en mac ... En la configuración del proyecto, especifique el tipo de carácter como 'no definido' o 'use unicode' o 'use multibyte'. Si dice 'no definido' entonces _UNICODE no está definido, si dice 'use unicode' entonces _UNICODE está definido. – Medran

2

Utilice el formato %ls que siempre significa wchar_t*.

+0

no es un problema con wchar_t siendo visto como su char * un problema con char * siendo visto como wchar_t. Además, no creo que% ls funcione en estudios visuales antiguos ... Gracias de todos modos neil. – Medran

+0

Disculpe, no pude encontrar una forma compatible de especificar un 'char *', pero en realidad busqué% ls en la documentación VS7.1, así que eso es bastante atrás. – Neil

+0

Sí puedo confirmar que% ls funciona al menos desde VS2008, que es en lo que estoy, gracias por eso. También lo encontré en la documentación y aparentemente es lo que debería haber estado usando en lugar de% S todo el tiempo, ya que supongo que% S es algo muy poco estándar. Pero realmente, ¿qué podría ser más no estándar que hacer que% s sea igual a un wchar_t? Lo único que pensé fue redirigir todo mi * wprint * a una función de envoltura que podría escribir que cambiaría el% s, según sea necesario. – Medran

Cuestiones relacionadas