2010-07-30 22 views
1

J'ai les belles fonctions de mon previous question, qui fonctionne très bien si je fais ceci:WideCharToMultiByte problème

wstring temp; 
wcin >> temp; 

string whatever(toUTF8(getSomeWString())); 

// store whatever, copy, but do not use it as UTF8 (see below) 

wcout << toUTF16(whatever) << endl; 

La forme originale est reproduite, mais entre forme contient souvent des caractères supplémentaires. Si j'entre par exemple àçé comme entrée et que j'ajoute une instruction cout << whatever, j'obtiendrai ┬à┬ç┬é en sortie. Puis-je toujours utiliser cette chaîne pour la comparer à d'autres, obtenues à partir d'une source ASCII? Ou demandé différemment: si je produisais ┬à┬ç┬é par l'UTF8 cout dans Linux, lirait-il àçé? Est-ce que le contenu en octets d'une chaîne àçé, lu en UTF8 linux par cin, exactement le même que ce que l'API Win32 me obtient?

Merci! PS: la raison pour laquelle je demande est parce que j'ai besoin d'utiliser beaucoup la chaîne pour la comparer à d'autres valeurs de lecture (comparaison et concaténation ...).

Répondre

5

Soit Commençons en me disant qu'il semble qu'il n'y a tout simplement pas moyen de sortie du texte UTF-8 à la console dans Windows via cout (en supposant que vous compilez avec Visual Studio). Ce que vous pouvez faire cependant pour vos tests est à la sortie de votre texte UTF-8 via l'API Win32 fn WriteConsoleA:

if(!SetConsoleOutputCP(CP_UTF8)) { // 65001 
    cerr << "Failed to set console output mode!\n"; 
    return 1; 
} 
HANDLE const consout = GetStdHandle(STD_OUTPUT_HANDLE); 
DWORD nNumberOfCharsWritten; 
const char* utf8 = "Umlaut AE = \xC3\x84/ue = \xC3\xBC \n"; 
if(!WriteConsoleA(consout, utf8, strlen(utf8), &nNumberOfCharsWritten, NULL)) { 
    DWORD const err = GetLastError(); 
    cerr << "WriteConsole failed with << " << err << "!\n"; 
    return 1; 
} 

Cette sortie devrait: Umlaut AE = Ä/ue = ü si vous définissez votre console (cmd.exe) d'utiliser la Lucida Console police.

Quant à votre question (prise de votre commentaire) si

une chaîne convertie API win23 est le même comme une chaîne de UTF8 brut (linux)

je vais dire oui: Étant donné une séquence de caractères Unicode, sa représentation UTF-16 (Windows wchar_t) convertie en une représentation UTF-8 (char) via la fonction WideCharToMultiByte donnera toujours la même séquence d'octets.

+1

Si vous utilisez WriteConsole de toute façon, vous pouvez également utiliser WriteConsoleW pour écrire directement la chaîne UTF-16, ce qui élimine la nécessité de SetConsoleOutputCP. – Philipp

+0

@Philipp - Oui, convertir d'abord utf16 en utf8 et ensuite utiliser WriteConsoleA n'a pas beaucoup de sens. Si les chaînes de l'application (test-) sont déjà utf8, cela pourrait quand même avoir du sens. –

1

Lorsque vous convertissez la chaîne en UTF 16 il s'agit d'un caractère large de 16 octets, vous ne pouvez pas le comparer aux valeurs ASCII car ils ne sont pas des valeurs de 16 octets. Vous devez les convertir pour comparer ou écrire une comparaison spécialisée à la fonction ASCII. Je doute que la coutume UTF8 dans linux produirait la même sortie correcte à moins que ce soit des valeurs ASCII normales, comme UTF8 UTF-8 encoding forms are binary-compatible with ASCII for code points below 128, et je suppose que UTF16 vient après UTF8 d'une manière simliar. La bonne nouvelle est qu'il y a beaucoup de converters écrits pour convertir ces chaînes en différents jeux de caractères.

+0

Je connais les conversions (je les utilise dans la question précédente à laquelle je suis lié, et je convertis exactement parce que je dois effectuer des comparaisons), et j'essaie d'établir si une chaîne convertie API API23 est la même une chaîne brute UTF8 (linux). 'cout' sur linux sort bien les caractères, c'est pourquoi il utilise UTF8 en premier lieu (eh bien, probablement aussi beaucoup d'autres raisons). La chose est, je ne sais pas si la chaîne '┬à┬ç┬é' est également présente dans une chaîne UTF8 brute. – rubenvb