2009-10-23 8 views
6

Comment convertir une chaîne wchar_t de majuscules en minuscules en C++?Conversion d'une chaîne de caractères large en minuscule en C++

La chaîne contient un mélange de caractères japonais, chinois, allemands et grecs.

Je pensais à l'aide towlower ...

http://msdn.microsoft.com/en-us/library/8h19t214%28VS.80%29.aspx

.. mais la documentation dit que:

La conversion cas de towlower est spécifique à la localisation. Seuls les caractères pertinents pour les paramètres régionaux en cours sont modifiés dans le cas.

Modifier: Peut-être que je devrais décrire ce que je fais. Je reçois une requête de recherche Unicode d'un utilisateur. C'est à l'origine en encodage UTF-8, mais je le convertis en widechar (je peux me tromper sur le libellé). Mon débogueur (VS2008) affiche correctement les caractères japonais, allemands, etc dans la "variable quick watch". Je dois passer par un autre ensemble de données en Unicode et trouver des correspondances de la chaîne de recherche. Bien que ce ne soit pas un problème pour moi lorsque la recherche est sensible à la casse, il est plus difficile de le faire insensible à la casse. Mon approche (peut-être naïve) pour résoudre le problème serait de convertir toutes les données d'entrée et de sortie en minuscules, puis de les comparer.

+3

une autre approche serait d'utiliser des algorithmes de comparaison qui ignorent la casse. Et le cas n'est pas votre seul problème. Sans normaliser la chaîne, les diacritiques par exemple peuvent être considérés comme faisant partie d'un ('é',' Õ'), ou plusieurs caractères individuels (''e',' ~ O'). Normalisation correcte (NFC/NFD/NFKC/NFKD) avant la comparaison est essentielle dans votre situation. – Abel

+0

Abel, s'il vous plaît postez-le comme une réponse appropriée afin qu'il puisse être upvoted comme il se doit. C'est à peu près la seule réponse correcte dans cette situation ... –

Répondre

9

Si votre chaîne contient tous ces caractères, le jeu de codes doit être basé sur Unicode. Si elle est implémentée correctement, Unicode (Chapitre 4 'Character Properties') définit les propriétés des caractères, notamment si le caractère est en majuscules et en minuscules, etc.

Étant donné ce préambule, la fonction towlower() de <wctype.h> est l'outil correct à utiliser. Si cela ne fonctionne pas, vous avez un problème QoI (qualité de la mise en œuvre) à discuter avec votre fournisseur. Si vous trouvez que le fournisseur ne répond pas, regardez les bibliothèques alternatives. Dans ce cas, vous pouvez envisager ICU (International Components for Unicode).

+2

Les mappages de cas Unicode, tels que spécifiés dans le document auquel vous avez lié, dépendent encore partiellement des paramètres régionaux. Quote: "SpecialCasing.txt - Contient des mappages de cas supplémentaires qui correspondent à plusieurs caractères, tels que" ß "à" SS ", ainsi que des mappages dépendant du contexte, avec des indicateurs pour les distinguer des mappages normaux, ainsi que _some mappages dépendant des paramètres régionaux. ". Donc 'tolower' ne peut pas éviter d'être spécifique à la locale. –

+0

@Pavel Ce processus est appelé "normalisation des chaînes Unicode", ce qui garantit que 'ß' et' ss' sont traités égaux (selon la forme de normalisation choisie) et Unicode contient des algorithmes neutres pour cela, sans ignorer le souhait pour les paramètres régionaux ou spécifiques à l'application. – Abel

+2

@Abel: la normalisation n'est pas une solution complète. Par exemple, dans certaines langues latines, les diacritiques disparaissent sur les lettres majuscules, mais pas dans les autres langues. Il n'y a aucun moyen de le savoir, sauf si vous savez dans quelle langue le texte est écrit. Ensuite, bien sûr, il y a le fameux "i" turc sans point - vous voulez 'İ' en minuscules à' i' et 'I' à lowecase à' ı' pour le turc, mais vous voulez 'I' en minuscule à' i' pour toute autre langue de l'alphabet latin. –

3

Vous avez un gros problème en main. Une locale japonaise n'aidera pas à convertir l'allemand et vice versa. Il y a des langues qui n'ont pas le concept de la captation non plus (toupper et les amis seraient un non-op ici, je suppose). Alors, pouvez-vous diviser votre chaîne en morceaux individuels de mots de la même langue? Si vous le pouvez, vous pouvez convertir les pièces et les corder.

+0

Le japonais et les autres langues idéographiques d'Asie de l'Est sont des exemples de langues principalement sans majuscules. –

+5

Non seulement cela, mais les langues individuelles peuvent avoir des opinions différentes sur la façon dont une lettre particulière devrait être supérieure/minuscule. Il n'y a tout simplement pas d'algorithme unique pour le faire correctement sur n'importe quelle chaîne Unicode aléatoire sans connaître la langue. –

+1

Bien que je sois d'accord avec cette évaluation, Unicode inclut des propriétés majuscules/minuscules indépendantes des paramètres régionaux, son utilisation décrite sous * 3.13 "Default Case Opreations" *, qui sont * à utiliser en l'absence de personnalisation pour des langues particulières *. la norme dit. – Abel

1

This SO answer montre comment travailler avec des facettes pour travailler avec plusieurs locales. Si c'est sur Windows, vous pouvez envisager d'utiliser les fonctions de l'API win32, si vous pouvez travailler avec C++ .NET (C++ géré), vous pouvez utiliser les fonctions char.ToLower et string.ToLower, qui sont compatibles Unicode.

0

Regardez _wcslwr_l dans <wchar.h> (MSDN).

Vous devriez être en mesure d'exécuter la fonction sur l'entrée pour chacun des paramètres régionaux.

+0

"Vous devriez être en mesure d'exécuter la fonction sur l'entrée pour chacun des paramètres régionaux." - Que se passe-t-il si deux paramètres régionaux de l'ensemble correspondent différemment au même caractère? –

+0

Comme mentionné dans d'autres commentaires, vous devez connaître la langue de chaque partie de la chaîne afin d'éviter ces cas. Il n'y a vraiment pas moyen de contourner cela. Je suggère simplement une fonction différente à utiliser pour gérer plus facilement le problème avec l'exécution de l'opération sur les paramètres régionaux actuels. –

Questions connexes