2010-02-08 7 views
2

Quelle est une bonne façon de comparer deux caractères individuels (char ou UTF-16 wchar_t s) en ignorant le cas?comparaison insensible à la casse de deux TCHAR

Une implémentation triviale serait supérieure ou minuscule les deux. L'un d'entre eux est-il considéré comme meilleur ou existe-t-il d'autres méthodes? Je comprends qu'une comparaison complètement correcte n'est pas possible avec tous les détails de l'Unicode. La comparaison est destinée principalement à l'analyse basique des fichiers de configuration et des micro-grammaires, donc la perfection n'est pas requise. Je suis à la recherche d'une implémentation pas trop mal sous la restriction de la comparaison par caractère.

[modifier]
Ces fichiers de configuration peuvent contenir des textes à l'utilisateur. En outre, lors de l'analyse des entrées utilisateur, je ne peux pas éviter le texte Unicode.

+0

Avez-vous besoin de _compare_ l'entrée de l'utilisateur? Si oui, avez-vous besoin de le faire de manière insensible à la casse? –

+0

Ouais - par ex. en autorisant à la fois "6kg" et "6KG". – peterchen

Répondre

2

Vous avez besoin de CompareStringEx. Il prend des caractères larges et a un drapeau insensible à la casse.

+0

voulez-vous dire "les mettre dans une chaîne de caractères unique"? – peterchen

+0

Oui. Je veux dire ça. – bmargulies

0

N'utilisez pas Unicode pour les fichiers de configuration si vous souhaitez une comparaison insensible à la casse basée sur ASCII. Utilisez ASCII pour ces fichiers. Ensuite, vous n'avez pas à vous soucier des paramètres régionaux.

0

Si vous souhaitez vous limiter aux mots-clés anglais (ASCII), il existe une manière triviale de faire la comparaison. Cela ne généralisera pas si vous voulez utiliser des lettres autres que A-Z dans vos mots-clés, mais cela fonctionne magnifiquement pour A-Z.

Si vous tenez compte du fait que l'une des valeurs que vous passez à cette fonction sera une bonne chaîne de mot clé connue contenant uniquement des caractères visibles dans la plage ASCII 32-127 (AZ, az, 0-9, la plupart des symboles) faire un simple bitmasking pour convertir les majuscules en minuscules.

bool IsKeywordMatch(LPCTSTR psz, LPCTSTR pszKey) 
{ 
    while (pszKey[0]) 
    { 
     if (psz[0] < 0x20) 
      return false; 

     if ((psz[0] & ~0x20) != (pszKey[0] & ~0x20)) 
     return false; 

     ++psz; 
     ++pszKey; 
    } 
    return true; 
} 

Ce code est pas une chaîne d'usage général comparer, elle est spécialisée pour comparer un bon mot-clé connu une chaîne d'entrée. Il traitera {} comme majuscule de [], `comme majuscule @, ~ comme majuscule ^, mais si l'une des entrées de cette fonction est garantie pour ne contenir aucun de ces caractères, cela n'aura aucune importance.

Il est destiné à être utilisé comme celui-ci

if (IsKeywordMatch(pszInput, "value")) 
1

d'abord les convertir en chaînes, par exemple faire un tableau de deux TCHARs, copiez votre TCHAR au premier et mettre le second à _T (» \ 0 '). Puis appelez lstrcmpi ou CompareString. Les deux peuvent être insuffisants selon vos besoins, mais ils sont un bon début. Par exemple, si vous voulez mettre à jour ß, ou si l'utilisateur utilise le turc et que vous voulez le mettre à jour, le faire vous-même est plus difficile que vous ne le pensiez.