2012-04-03 13 views
5

Ive ha un progetto multi piattaforma che compila grandiosamente su mac, ma su windows tutte le mie chiamate swprintf con% s cercano un wchar_t invece di il char * im che lo passa. Risulta che M $ ha pensato che sarebbe stato divertente rendere% s qualcosa di diverso da char * nelle funzioni di caratteri estesi ... http://msdn.microsoft.com/en-us/library/hf4y5e3w.aspxvisual studio swprintf sta rendendo tutti i miei formattatori di% s vogliono wchar_t * invece di char *

In ogni caso, sto cercando un trucco di codifica creativo che sia meglio che mettere ifdef else finisce intorno Chiamata di ogni stringa estesa

risposta

4

Visual Studio 14 CTP1 e versioni successive trattano sempre %s come una stringa stretta (char*) a meno che non si definisca _CRT_STDIO_LEGACY_WIDE_SPECIFIERS. Inoltre ha aggiunto l'estensione del modificatore della lunghezza T che associa a ciò che MS chiama la larghezza "naturale". Per sprintf%Ts è char* e per swprintf%Ts è wchar_t*.


In Visual Studio 13 e precedenti %s/%c è mappato alla larghezza naturale della stringa di funzioni/formato e %S/%C viene mappato al contrario del naturale 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"); 

È può anche forzare una larghezza specifica utilizzando un modificatore di lunghezza: %ls, %lc, %ws e %wc significa sempre wchar_t e %hs e %hc sono un sempre char. (Documentata per VS2003 here e VC6 here (Non sei sicuro di %ws e quando è stato davvero aggiunto))

Mapping %s alla larghezza naturale della funzione è stato davvero utile nei giorni di Win9x vs WinNT, utilizzando il tchar.h header potresti creare versioni narrow e wide dalla stessa fonte. Quando _UNICODE è definito le funzioni tchar.h mappa per le ampie funzioni e TCHAR è wchar_t, altrimenti si utilizzano le funzioni strette e TCHAR è char:

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

C'è una convenzione simile a quello utilizzato dai file di intestazione di Windows SDK e il alcune funzioni di formattazione esistenti (wsprintf, wvsprintf, wnsprintf e wvnsprintf), ma sono controllate da UNICODE e TEXT e non da e _T/_TEXT.

Probabilmente hanno 3 scelte da fare un lavoro di progetto multi-piattaforma su Windows se si desidera supportare più grandi compilatori di Windows:

1) compilare come una stretta progetto di stringa su Windows, probabilmente non è una buona idea e nel tuo caso swprintf continuerà a trattare% s come wchar_t *.

2) Uso personalizzato definisce simile a come inttypes.stringhe di formato h funzionano:

#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) creare la propria versione personalizzata di swprintf e utilizzarlo con Visual Studio 13 e precedenti.

+0

Im davvero non so come usarlo, nei miei test quando _UNICODE è definito o non definito il comportamento è lo stesso swprintf% s si aspetta un wchar_t e non un char *. Per quanto riguarda le estensioni MS, sai se c'è un modo per far sì che gcc li usi? – Medran

+0

Sei sicuro che il tuo ambiente non lo stia definendo per te (nelle impostazioni del progetto in VS)? Se da gcc intendi MinGW allora sì, MinGW può utilizzare il tempo di esecuzione MS C, vedere http://stackoverflow.com/questions/6729013/mingw-printf-size-specification-character-h – Anders

+0

senza gcc su Mac ... Nelle impostazioni del progetto specifichi il tipo di carattere come "non definito" o "usa unicode" o "usa multibyte". Se dici "non definito" allora _UNICODE non è definito, se dici "usa unicode" allora _UNICODE è definito. – Medran

2

Utilizzare il formato %ls che indica sempre wchar_t*.

+0

il suo non è un problema con wchar_t essere visto come char * il suo un problema con il char * essere visto come wchar_t. Inoltre, non penso che funzioni su vecchi studi visivi ... Comunque grazie neil. – Medran

+0

Spiacente, non sono riuscito a trovare un modo compatibile per specificare un 'char *', ma in realtà ho cercato% ls nella documentazione di VS7.1, quindi è abbastanza indietro. – Neil

+0

Sì, posso confermare che% ls funziona almeno fino a VS2008, che è quello che sto facendo, grazie per quello. L'ho trovato anche nella documentazione e apparentemente è quello che avrei dovuto usare al posto di% S fin dall'inizio, perché immagino che% S sia una cosa non standard. Ma in realtà quello che potrebbe essere più non standard di rendere% s uguale a un wchar_t. L'unica cosa che ho pensato è di reindirizzare tutto il mio * wprint * a una funzione wrapper che potrei scrivere che cambierebbe il% s come necessario. – Medran

Problemi correlati