2009-01-14 6 views
10

J'écris quelques tests unitaires qui vont vérifier notre traitement des diverses ressources qui utilisent d'autres jeux de caractères en dehors de l'alphabet latin normal: cyrillique, hébreu, etc.Comment puis-je intégrer des constantes de chaîne Unicode dans un fichier source?

Le problème que j'ai est que je ne peux pas trouver un façon d'intégrer les attentes dans le fichier source de test: voici un exemple de ce que je suis en train de faire ...

/// 
/// Protected: TestGetHebrewConfigString 
/// 
void CPrIniFileReaderTest::TestGetHebrewConfigString() 
{ 
    prwstring strHebrewTestFilePath = GetTestFilePath(strHebrewTestFileName); 
    CPrIniFileReader prIniListReader(strHebrewTestFilePath.c_str()); 
    prIniListReader.SetCurrentSection(strHebrewSubSection); 

    CPPUNIT_ASSERT(prIniListReader.GetConfigString(L"דונדארןמע") == L"דונהשךוק")); 
} 

Ce travail ne marche pas tout simplement. Auparavant, je travaillais autour de cette aide d'une macro qui appelle une routine pour transformer une chaîne étroite à une grande chaîne (nous utilisons towstring partout dans nos applications il est donc le code existant)

#define UNICODE_CONSTANT(CONSTANT) towstring(CONSTANT) 

wstring towstring(LPCSTR lpszValue) 
{ 
    wostringstream os; 
    os << lpszValue; 
    return os.str(); 
} 

L'affirmation dans le test ci-dessus puis est devenu:

CPPUNIT_ASSERT(prIniListReader.GetConfigString(UNICODE_CONSTANT("דונדארןמע")) == UNICODE_CONSTANT("דונהשךוק")); 

Cela a fonctionné OK sur OS X, mais maintenant je suis le portage vers linux et je trouve que les tests sont tous échouent: il se sent tout plutôt hackish aussi bien. Quelqu'un peut-il me dire s'ils ont une meilleure solution à ce problème?

Répondre

18

Un moyen fastidieux mais portable est de construire vos chaînes en utilisant des codes d'échappement numériques. Par exemple:

wchar_t *string = L"דונדארןמע"; 

devient:

wchar_t *string = "\x05d3\x05d5\x05e0\x05d3\x05d0\x05e8\x05df\x05de\x05e2"; 

Vous devez convertir tous vos caractères Unicode échappe numériques. De cette façon, votre code source devient indépendant de l'encodage.

Vous pouvez utiliser des outils en ligne pour la conversion, tels que this one. Il génère le format d'échappement JavaScript \uXXXX, donc il suffit de rechercher & remplacer \u avec \x pour obtenir le format C.

+0

Dans Windows wchar_t est 16 bits et tout le monde est 32 bits.Est-ce que cela a un effet sur ce que les littéraux hexadécimaux doivent être listés? Ou est-ce que '\ x05d3' fonctionne aussi bien pour 16 et 32 ​​bits? –

+1

Il n'y a pas de limite au nombre de chiffres hexadécimaux après \ x, donc cela devrait fonctionner de la même manière quelle que soit sizeof (wchar_t). Voir ce sujet pour plus d'informations: http://stackoverflow.com/questions/2735101/unicode-escaping-in-c-c – fbonnet

11

Vous devez indiquer à GCC l'encodage que votre fichier utilise pour coder ces caractères dans le fichier. Utilisez l'option -finput-charset=charset, par exemple -finput-charset=UTF-8. Ensuite, vous devez lui indiquer le codage utilisé pour ces littéraux de chaîne au moment de l'exécution. Cela va déterminer les valeurs des éléments wchar_t dans les chaînes. Vous définissez ce codage en utilisant -fwide-exec-charset=charset, par exemple -fwide-exec-charset=UTF-32. Méfiez-vous que la taille de l'encodage (utf-32 nécessite 32 bits, utf-16 nécessite 16 bits) ne doit pas dépasser la taille de wchar_t utilise gcc.

Vous pouvez ajuster cela. Cette option est principalement utile pour compiler des programmes pour wine, conçus pour être compatibles avec Windows. L'option est appelée -fshort-wchar, et sera probablement 16 bits au lieu de 32 bits, ce qui est sa largeur habituelle pour gcc sur Linux.

Ces options sont décrites plus en détail dans man gcc, la page de manuel gcc.

0
#define UNICODE_CONSTANT(CONSTANT) towstring(CONSTANT) 

wstring towstring(LPCSTR lpszValue) { 
    wostringstream os; 
    os << lpszValue; 
    return os.str(); 
} 

Ceci ne convertit pas du tout entre les codages Unicode, ce qui nécessite une routine dédiée. Vous devez conserver votre code source et vos codages de données unifiés (la plupart des utilisateurs utilisent UTF-8), puis les convertir au codage spécifique au système d'exploitation si nécessaire (par exemple, UTF-16 sur Winders).

Questions connexes