2017-06-27 3 views
1

Quelle est la manière recommandée de lire une entrée utilisateur qui peut avoir des caractères spéciaux avec, par exemple, des accents, si on ne sait pas dans quel locale il est entré.Comment entrer et vérifier en toute sécurité et de manière portative les caractères d'accent

Comment comparer en toute sécurité un caractère de cette entrée d'utilisateur s'il s'agit d'une entrée spéciale dont j'ai besoin?

C'est un exemple de code pour illustrer l'intention:

#include <iostream> 
using namespace std; 

int main() { 
    char txt[10]; 
    cin.getline(txt, sizeof(txt)); 
    if(txt[0] == 'á') 
     cout << "Special character found\n"; 
} 

Le problème est:

warning: multi-character character constant [-Wmultichar] 
    if(txt[0] == 'á') 
       ^

Si j'utilise L'á' aussi large caractère littéral, il ne correspond pas à, depuis l'entrée n'est pas large. Si j'utilise wchar_t et wcin.getline pour que l'utilisateur saisisse des caractères larges, cela peut fonctionner sur certains systèmes et pas sur d'autres, selon l'environnement et les paramètres régionaux.

Comment surmonter ce problème en toute sécurité et en toute sécurité? Merci!

+2

Vous voudrez peut-être envisager d'utiliser une bibliothèque unicode comme [ICU] (http://site.icu-project.org/) – NathanOliver

+0

La meilleure approche, ou notre préféré ? Je me suis bien débrouillé en utilisant UTF8 en interne, dans Windows, je dois convertir en UTF-16 pour l'affichage et l'entrée de l'interface utilisateur, mais ça vaut le coup. J'ai utilisé exclusivement 'boost :: locale :: conv :: utf_to_utf' pour faire les conversions. –

Répondre

1

Si vous ne connaissez pas vos paramètres régionaux et que vous devez rendre votre solution portable, je crains qu'il n'y ait pas de solution C++ standard pour cela. Et je ne suis pas sûr qu'il y en aura jamais, compte tenu de Windows utilisant UTF-16. Donc, si vous avez besoin d'une «solution prête à l'emploi», il serait probablement logique de vérifier la bibliothèque mentionnée dans NathanOliver's comment. Cela dit, bien que la prise en charge d'Unicode reste un point sensible de C++ (et c'est vraiment triste d'écrire ces mots en 2017), il y a certaines améliorations qui sont venues avec C++ 11. Donc, dans le cas où la conversion manuelle est une option pour vous, vous pouvez bénéficier de certains de ses goodies.

Par exemple, voici un code C++ 11 valide.

unsigned char euroUTF8[] = { 0xE2, 0x82, 0xAC, 0x00 }; // Euro sign UTF8 

wstring_convert<codecvt_utf8<wchar_t>> converter_UTF8_wchar; 
wstring euroWideStr = converter_UTF8_wchar.from_bytes((char*)euroUTF8); 
wcout << euroWideStr << endl; 

string euroNarrowStr = converter_UTF8_wchar.to_bytes(euroWideStr); 
cout << euroNarrowStr << endl; 

Pour plus de vérifier le contexte this article