2010-11-25 15 views
2

Je code suivant:Facet.narrow() utilise le caractère par défaut où il ne devrait pas en utf-8

#include <iostream> 
#include <string> 
#include <locale> 
#include <algorithm> 

using namespace std; 

int main() 
{ 
locale loc("cs_CZ.utf-8"); 
std::wstring Str = L"aaěščřžýáíéaa"; 
std::string Str2; 
const ctype<wchar_t> &ct = std::use_facet<std::ctype<wchar_t> >(loc); 
for(std::wstring::const_iterator It = Str.begin(); It < Str.end(); ++It) 
    Str2 += ct.narrow(*It, '-'); 
std::cout << Str2 <<std::endl; 
} 

qui produit cette sortie:

[email protected]:/tmp$ ./a.out 
aa---------aa 

Mais si j'utilise cs_CZ. ISO-8859-2 en tant que locale cible, la sortie est correcte:

[email protected]:/tmp$ ./a.out | iconv -f ISO-8859-2 -t utf-8 
aaěščřžýáíéaa 

Alors pourquoi ne pas fonctionner correctement même avec utf-8? J'ai besoin de convertir les caractères de wchar_t en char quel que soit l'encodage utilisé par ce système particulier.

Répondre

2

Je crois que la facette codecvt devrait faire l'affaire. Ctype ne peut gérer que les codages à un seul octet pendant que vous essayez de convertir en codage multi-octets. Ne renvoie pas le type de la méthode ctype :: narrow() qui vous dérange?

+0

Droite. Malheureusement, 'ctype' est hérité de C, et est fondamentalement incompatible avec les encodages multi-octets comme utf-8 car il suppose une traduction 1: 1 entre' wchar_t' et 'char'. –

+0

Oui, c'est le cas. Je voulais juste confirmer mes soupçons :) Je suppose que je deviens un peu rouillé avec mes compétences c/C++ :) Quoi qu'il en soit codecvt semble être ce dont j'ai besoin ... – Trakhan

+0

Méfiez-vous codecvt_byname faible portabilité. Soyez prêt à écrire des wrappers différents d'initializaton pour que votre code fonctionne sur Windows. – Basilevs