Gestion du tri dans vos applications

Certaines applications, telles que Microsoft Active Directory, Microsoft Exchange et Microsoft Access, conservent une base de données triable de chaînes de paramètres régionaux et de langage indexées par nom (chaîne UTF-16) et leurs pondérations de tri associées.

Le tri est généralement intuitif pour les utilisateurs dans leurs propres paramètres régionaux. Toutefois, il peut être non intuitif pour les développeurs d’applications. Cette rubrique décrit les considérations relatives à la gestion du tri dans vos applications. Le tri peut être linguistique ou ordinal (non linguistique).

Fonctions de tri

Vous pouvez utiliser diverses fonctions de tri dans vos applications :

Généralement, les fonctions de tri évaluent les chaînes caractère par caractère. Toutefois, de nombreuses langues ont des éléments à plusieurs caractères, comme la paire à deux caractères « CH » dans l’espagnol traditionnel. CompareString et CompareStringEx utilisent l’identificateur ou le nom des paramètres régionaux fournis par l’application pour identifier les éléments à plusieurs caractères. En revanche, lstrcmp et lstrcmpi utilisent les paramètres régionaux de l’utilisateur.

Un autre exemple est le vietnamien, qui contient de nombreux éléments à deux caractères, tels que les majuscules valides, la casse de titre et les formes minuscules de « GI », qui sont respectivement « GI », « Gi » et « gi ». L’un de ces formulaires est traité comme un élément de tri unique et, si la casse est ignorée, la compare comme égale. Toutefois, étant donné que « gI » n’est pas valide en tant qu’élément unique, CompareStringEx, lstrcmp et lstrcmpi traitent « gI » comme deux éléments distincts.

Les fonctions CompareString, CompareStringEx, lstrcmp, lstrcmpi, LCMapString,LCMapStringEx, FindNLSString et FindNLSStringEx utilisent toutes par défaut une technique de « tri de mots ». Pour ce type de type, tous les signes de ponctuation et autres caractères non alphanumériques, à l’exception du trait d’union et de l’apostrophe, précèdent tout caractère alphanumérique. Le trait d’union et l’apostrophe sont traités différemment des autres caractères nonalphanumériques pour s’assurer que des mots tels que « coop » et « co-op » restent ensemble dans une liste triée.

Au lieu d’un tri de mots, l’application peut demander une technique de « tri de chaîne » à partir des fonctions de tri en spécifiant l’indicateur SORT_STRINGSORT. Un tri de chaîne traite le trait d’union et l’apostrophe comme n’importe quel autre caractère nonalphanumé. Leurs positions dans la séquence de tri se trouvent avant les caractères alphanumériques.

Le tableau suivant compare les résultats d’un tri de mot avec les résultats d’un tri de chaîne.

Word Trier Tri de chaîne
billet bill’s
Factures billet
bill’s Factures
Ne Ne
Cant Ne
Ne Cant
con coopération
Coop con
coopération Coop

 

Trier les chaînes linguistiquement

Les fonctions CompareString et CompareStringEx testent l’égalité linguistique. Vos applications doivent utiliser ces fonctions avec les paramètres régionaux appropriés pour le tri linguistique des chaînes.

Notes

Pour une compatibilité avec Unicode, une application doit préférer CompareStringEx ou la version Unicode de CompareString. Une autre raison de préférer CompareStringEx est que Microsoft migre vers l’utilisation de noms de paramètres régionaux au lieu d’identificateurs régionaux pour les nouveaux paramètres régionaux, pour des raisons d’interopérabilité. Toute application qui s’exécute uniquement sur Windows Vista et versions ultérieures doit utiliser CompareStringEx.

 

Une autre façon de tester l’égalité linguistique consiste à utiliser lstrcmp ou lstrcmpi, qui utilisent toujours un tri de mots. La fonction lstrcmpi appelle CompareString avec l’indicateur NORM_IGNORECASE, tandis que lstrcmp l’appelle sans cet indicateur. Pour obtenir une vue d’ensemble de l’utilisation des fonctions wrapper, consultez Chaînes.

Les fonctions récupèrent les résultats linguistiques appropriés pour tous les paramètres régionaux. Les attentes des utilisateurs pour différents paramètres régionaux peuvent différer considérablement dans le comportement de tri, comme illustré dans les exemples suivants.

  • De nombreux locaux assimilent l’ae ligature (æ) aux lettres ae. Cependant, islandais (Islande) le considère comme une lettre distincte et la place après Z dans la séquence de tri.
  • L’anneau A (Å) trie normalement avec une simple différence diacritique par rapport à A. Cependant, suédois (Suède) place l’anneau A après Z dans la séquence de tri.

Les fonctions tentent de vérifier rigoureusement que les points de code définis dans la norme Unicode sont canoniquement égaux à une chaîne de points de code équivalents. Par exemple, le point de code qui représente un « u » minuscule avec une dieresis (ü) est canoniquement égal à un « u » minuscule combiné avec la dieresis ( ̈). Notez toutefois que l’équivalence canonique n’est pas toujours possible.

Étant donné que presque toutes les données entrées à l’aide de claviers Windows et d’éditeurs de méthode d’entrée (GÉ) sont conformes à la normalisation de forme C définie dans la norme Unicode, la conversion des données entrantes à partir d’autres plateformes à l’aide des fonctions de normalisation UNICODE NLS fournit des résultats plus cohérents, en particulier pour les paramètres régionaux qui utilisent le script tibétain ou le script Hangûl pour le hangûl moderne. Pour plus d’informations sur la prise en charge de la normalisation Unicode dans Windows Vista et versions ultérieures, consultez Utilisation de la normalisation Unicode pour représenter des chaînes.

Lorsque la comparaison de chaînes suit la préférence de langue de l’utilisateur, par exemple, lors du tri des éléments d’un contrôle ListView ordonné, l’application peut effectuer l’une des opérations suivantes :

  • Appelez lstrcmp ou lstrcmpi avec les paramètres régionaux de l’utilisateur.
  • Appelez CompareString ou CompareStringEx pour définir des paramètres régionaux pour la comparaison, passer des indicateurs supplémentaires, incorporer des caractères Null ou passer des longueurs explicites pour faire correspondre des parties d’une chaîne.

Lorsque les résultats de la comparaison doivent être cohérents, quels que soient les paramètres régionaux, par exemple, lors de la comparaison des données récupérées avec une liste prédéfinie ou une valeur interne, l’application doit utiliser CompareString ou CompareStringEx avec le paramètre Paramètres régionaux défini sur LOCALE_INVARIANT. Pour CompareString, l’un des appels suivants correspond même si mystr est « INLAP ». Dans ce cas, un appel à lstrcmpi sensible aux paramètres régionaux échoue si les paramètres régionaux actuels sont vietnamiens.

Sur Windows XP :

int iReturn = CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, mystr, -1, _T("InLap"), -1);

Sur les systèmes d’exploitation antérieurs :

DWORD lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
int iReturn = CompareString(lcid, NORM_IGNORECASE, mystr, -1, _T("InLap"), -1);

Trier les chaînes ordinally

Pour le tri ordinal (non linguistique), vos applications doivent toujours utiliser la fonction CompareStringOrdinal .

Notes

Cette fonction est uniquement disponible pour Windows Vista et versions ultérieures.

 

CompareStringOrdinal compare deux chaînes Unicode pour tester l’égalité binaire, par opposition à l’égalité linguistique. Les noms de fichiers NTFS, les variables d’environnement et les noms des mutex, des canaux nommés ou des maillots sont des exemples de ces chaînes non linguistiques. À l’exception de l’option d’insensibilité à la casse, cette fonction ignore toutes les équivalences non binaires. Contrairement à d’autres fonctions de tri, il teste l’égalité de tous les points de code, y compris ceux qui ne sont pas pris en compte dans les schémas de tri linguistique.

Toutes les instructions suivantes s’appliquent à CompareStringOrdinal dans les comparaisons binaires, mais pas à CompareString, CompareStringEx, lstrcmp ou lstrcmpi.

  • Les séquences canoniquement équivalentes en Unicode, telles que LETTRE MINUSCULE LATINE A AVEC ANNEAU AU-DESSUS (U+00e5) et LETTRE MINUSCULE LATINE A + ANNEAU COMBINÉ AU-DESSUS (U+0061 U+030a), ne sont pas égales même si elles semblent identiques (« å »).
  • Les chaînes canoniquement similaires en Unicode, telles que LETTRE LATINE MINUSCULE Y (U+028f) et LETTRE MAJUSCULE LATINE Y (U+0059), qui sont très similaires (« ʏ » et « Y ») et ne varient que selon certaines pondérations de cas particulières dans les tables linguistiques, sont considérées comme des caractères totalement différents. Même si l’application affecte à bIgnoreCase la valeur TRUE, ces chaînes sont différentes.
  • Les points de code qui sont définis mais qui n’ont pas de poids de tri linguistique, tels que ZERO WIDTH JOINER (U+200d), sont traités comme ayant leurs pondérations de points de code.
  • Les points de code qui sont définis dans les versions ultérieures d’Unicode mais qui n’ont aucun poids dans les tables linguistiques actuelles sont traités comme ayant leurs pondérations de points de code.
  • Les points de code non définis par Unicode sont traités comme ayant leurs pondérations de points de code.
  • Lorsque l’application définit bIgnoreCase sur TRUE, la fonction mappe la casse à l’aide de la table de classement supérieur du système d’exploitation, au lieu des informations contenues dans les tables de tri linguistique. Par conséquent, le mappage est indépendant des paramètres régionaux.

Pour plus d’informations sur les séquences canoniquement équivalentes en Unicode et les chaînes canoniquement similaires dans Unicode, consultez Utilisation de la normalisation Unicode pour représenter des chaînes.

Trier les points de code

Certains points de code Unicode n’ont pas de poids, par exemple, ZERO WIDTH NON JOINER, U+200c. Les fonctions de tri évaluent intentionnellement les points de code sans poids comme équivalents, car ils n’ont pas de poids dans le tri. Sur Windows Vista et versions ultérieures, l’application peut trier ces points de code en appelant les fonctions de comparaison de chaînes NLS, en particulier CompareStringOrdinal, pour l’évaluation de tous les points de code dans un sens littéral et binaire, par exemple, dans la validation de mot de passe. Sur les systèmes d’exploitation antérieurs à Windows Vista, l’application doit utiliser la fonction de runtime C strcmp ou wcscmp.

Les fonctions de tri ignorent les diacritiques, telles que NON ESPACEMENT BREVE, U+0306, lorsque l’application spécifie l’indicateur hlink_NONSPACE. De même, ces fonctions ignorent les symboles, par exemple, EQUALS SIGN, U+003d , lorsque l’indicateur hlink_SYMBOLS est spécifié. Sur Windows Vista et versions ultérieures, l’application appelle CompareStringOrdinal pour l’évaluation des points de code diacritiques et de symboles dans un sens binaire littéral. Sur les systèmes d’exploitation antérieurs à Windows Vista, l’application doit utiliser strcmp ou wcscmp.

Certains points de code, tels que 0xFFFF et 0x058b, ne sont actuellement pas attribués dans Unicode. Ces points de code ne reçoivent aucun poids dans le tri et ne doivent jamais être passés aux fonctions de tri. L’application doit utiliser IsNLSDefinedString pour détecter des points de code non Unicode dans un flux de données.

Notes

Les résultats d’IsNLSDefinedString peuvent varier en fonction de la version Unicode transmise si un caractère est ajouté à Unicode dans une version ultérieure et qu’il est ensuite ajouté aux tables de tri Windows. Pour plus d’informations, consultez Utiliser le contrôle de version de tri.

 

Trier les chiffres en tant que nombres

Sur Windows 7 et versions ultérieures, l’application peut appeler CompareString, CompareStringEx, LCMapString ou LCMapStringEx à l’aide de l’indicateur SORT_DIGITSASNUMBERS. Cet indicateur prend en charge le tri qui traite les chiffres comme des nombres, par exemple, le tri de « 2 » avant « 10 ».

Notez que l’utilisation de cet indicateur n’est pas appropriée pour les chiffres hexadécimaux tels que les suivants.

01AF
1BCD
002A
12FA
AB1C
AB02
AB12

Dans ce cas, les « nombres » sont triés dans l’ordre, mais l’utilisateur perçoit une liste hexadécimale mal triée.

Chaînes de mappage

L’application utilise la fonction LCMapString ou LCMapStringEx pour mapper des chaînes, si LCMAP_SORTKEY n’est pas spécifié. Une chaîne mappée est terminée par null si la chaîne source est terminée par null.

Lors de la transformation entre majuscules et minuscules, la fonction ne garantit pas qu’un caractère unique sera mappé à un seul caractère. Par exemple, les indicateurs LCMAP_LOWERCASE et LCMAP_UPPERCASE peuvent mapper le sharp S allemand (« ß ») à lui-même. L’indicateur LCMAP_UPPERCASE peut également mapper « ß » à « SS » et l’indicateur LCMAP_LOWERCASE peut mapper « SS » à « ß ». Le comportement dépend de la version NLS.

Lors de la transformation entre majuscules et minuscules, la fonction n’est pas sensible au contexte. Par exemple, alors que l’indicateur de LCMAP_UPPERCASE mappe correctement à la fois le sigma minuscule grec (« σ ») et le sigma final grec minuscule (« ς ») au sigma majuscule grec (« Σ »), l’indicateur LCMAP_LOWERCASE mappe toujours « Σ » à « σ », jamais à « ς ».

Par défaut, la fonction mappe le « i » en minuscules à la majuscule « I », même si le paramètre Paramètres régionaux spécifie le turc ou l’azerbaïdjan. Pour remplacer ce comportement pour le turc ou l’azerbaïdjan, l’application doit spécifier LCMAP_LINGUISTIC_CASING. Si cet indicateur est spécifié avec les paramètres régionaux appropriés, « ı » (minuscules dotless I) est la forme minuscule de « I » (I sans point majuscule) et « i » (I en minuscules) est la forme minuscule de « İ » (majuscules pointillées I).

Si l’indicateur LCMAP_HIRAGANA est spécifié pour mapper des caractères katakana à des caractères hiragana et que LCMAP_FULLWIDTH n’est pas spécifié, LCMapString ou LCMapStringEx mappe uniquement les caractères pleine largeur à hiragana. Dans ce cas, tous les caractères katakana demi-largeur sont placés comme dans la chaîne de destination, sans mappage à hiragana. L’application doit spécifier LCMAP_FULLWIDTH pour mapper des caractères katakana demi-largeur à hiragana. La raison de cette restriction est que tous les caractères hiragana sont des caractères de pleine largeur.

Si l’application doit supprimer des caractères de la chaîne source, elle peut appeler la fonction de mappage avec les indicateurs NORM_IGNORESYMBOLS et NORM_IGNORENONSPACE définis, et tous les autres indicateurs effacés. Si l’application effectue cette opération avec une chaîne source qui n’est pas terminée par null, il est possible que la fonction retourne une chaîne vide et ne retourne pas d’erreur.

Créer des clés de tri

Lorsque l’application spécifie LCMAP_SORTKEY, LCMapString ou LCMapStringEx génère une clé de tri, un tableau binaire de valeurs d’octets. La clé de tri n’est pas une chaîne true et ses valeurs représentent le comportement de tri de la chaîne source, mais ne sont pas des valeurs d’affichage significatives.

Notes

La fonction ignore le kashida arabe pendant la génération d’une clé de tri. Si une application appelle la fonction pour créer une clé de tri pour une chaîne contenant un kashida arabe, la fonction ne crée aucune valeur de clé de tri.

 

La clé de tri peut contenir un nombre impair d’octets. L’indicateur LCMAP_BYTEREV inverse uniquement un nombre pair d’octets. Le dernier octet (placé en position impaire) de la clé de tri n’est pas inversé. Si l’octet qui se termine 0x00 est un octet de position impaire, il reste le dernier octet de la clé de tri. Si l’octet de fin 0x00 est un octet à position égale, il échange des positions avec l’octet qui le précède.

Lors de la génération de la clé de tri, la fonction traite le trait d’union et l’apostrophe différemment des autres symboles de ponctuation, de sorte que les mots tels que « coop » et « co-op » restent ensemble dans une liste. Tous les symboles de ponctuation autres que le trait d’union et l’apostrophe trient avant les caractères alphanumériques. L’application peut modifier ce comportement en définissant l’indicateur SORT_STRINGSORT, comme décrit dans Trier les fonctions.

Lorsqu’elle est utilisée dans memcmp, la clé de tri produit le même ordre que lorsque la chaîne source est utilisée dans CompareString ou CompareStringEx. La fonction memcmp doit être utilisée au lieu de strcmp, car la clé de tri peut avoir des octets null incorporés.

Utiliser le contrôle de version de tri

Une table de tri a deux nombres qui identifient sa version : la version définie et la version NLS. Les deux nombres sont des valeurs DWORD, composées d’une valeur majeure et d’une valeur mineure. Le premier octet d’une valeur est réservé, les deux octets suivants représentent la version principale et le dernier octet représente la version mineure. En termes hexadécimaux, le modèle est de 0xRRMMMMmm, où R est égal à Réservé, M à majeur et m à mineur. Par exemple, une version majeure de 3 avec une version mineure de 4 est représentée comme 0x304.

La version définie identifie le répertoire des points de code et est identique pour tous les paramètres régionaux. La version principale est incrémentée pour indiquer les modifications apportées aux points de code existants. La version mineure est incrémentée pour indiquer que des points de code ont été ajoutés, mais qu’aucun point de code existant n’a été modifié.

La version NLS est spécifique à un identificateur de paramètres régionaux ou à un nom de paramètres régionaux, et suit les modifications apportées aux pondérations de points de code pour les paramètres régionaux affectés. La version principale s’incrémente lorsque les pondérations sont modifiées pour les points de code qui étaient déjà triables. La version mineure s’incrémente lorsque de nouveaux points de code se voient attribuer des pondérations, mais que toutes les autres pondérations de points de code précédemment triables restent inchangées.

Notes

Pour une version majeure, un ou plusieurs points de code sont modifiés afin que l’application doit réindexer toutes les données pour que les comparaisons soient valides. Pour une version mineure, rien n’est déplacé, mais des points de code sont ajoutés. Pour ce type de version, l’application doit uniquement réindexer les chaînes avec des valeurs auparavant non triables.

 

Important

La version principale a été modifiée dans Windows 8. Les données créées sous des versions antérieures de Windows doivent être réindexées.

 

Les versions définies et NLS s’appliquent aux points de code triables récupérés à l’aide de la fonction LCMapString ou LCMapStringEx avec l’indicateur LCMAP_SORTKEY, et également utilisés par les fonctions CompareString, CompareStringEx, FindNLSString et FindNLSStringEx . Si un ou plusieurs points de code d’une chaîne ne sont pas triables, la fonction IsNLSDefinedString retourne FALSE lorsque cette chaîne lui est passée en tant que paramètre.

L’application peut appeler GetNLSVersion ou GetNLSVersionEx pour récupérer à la fois la version définie et la version NLS pour une table de tri.

Indexer la base de données

Pour des raisons de performances, l’application doit suivre cette procédure lors de l’indexation de la base de données.

Pour indexer correctement la base de données

  1. Pour chaque fonction, stockez la version NLS, les clés de tri de cette version et une indication de tri pour chaque chaîne indexée.
  2. Lorsque la version mineure est incrémentée, réindexez les chaînes précédemment non triables. Les chaînes affectées dans cette mise à jour doivent être limitées à celles pour lesquelles IsNLSDefinedString a précédemment retourné FALSE.
  3. Lorsque la version principale augmente, réindexez toutes les chaînes, car les pondérations mises à jour peuvent modifier le comportement de n’importe quelle chaîne. Les versions principales sont très peu fréquentes.

Des problèmes d’indexation de base de données peuvent survenir pour les raisons suivantes :

  • Un système d’exploitation ultérieur peut définir des points de code qui ne sont pas définis pour un système d’exploitation antérieur, ce qui modifie le tri.
  • Les points de code peuvent avoir des pondérations de tri différentes selon les systèmes d’exploitation, en raison des corrections apportées à la prise en charge linguistique.

Pour réduire la nécessité de réindexer la base de données dans ces circonstances, l’application peut utiliser IsNLSDefinedString pour différencier les chaînes définies des chaînes non définies afin que l’application puisse rejeter les chaînes avec des points de code non définis. L’utilisation de GetNLSVersion ou GetNLSVersionEx permet à l’application de déterminer si une modification NLS affecte les paramètres régionaux utilisés pour une table d’index particulière. Si la modification n’a aucun effet sur les paramètres régionaux, l’application n’a pas besoin de réindexer la table.

Exemples

Le tableau suivant illustre les effets de certains indicateurs utilisés avec les fonctions de tri. Dans chaque cas, la sélection des indicateurs détermine si deux caractères différents sont considérés comme égaux à des fins de tri.

Caractère 1 Caractère 2 Default NORM_IGNOREWIDTH NORM_IGNOREKANA NORM_IGNOREWIDTH| NORMIGNOREKANA
"あ"
U+3042 LETTRE HIRAGANA A
"ガ"
LETTRE KATAKANA U+30A2 A
Inégale Inégale Égal à Égal à
"オ"
LETTRE KATAKANA U+FF75 DEMI-CHASSE O
"オ"
LETTRE KATAKANA U+30AA O
Inégale Égal à Inégale Égal à
« B »
U+FF22 FULLWIDTH LETTRE MAJUSCULE LATINE B
« B »
U+0042 LETTRE MAJUSCULE LATINE B
Inégale Égal à Inégale Égal à

 

Utilisation de la prise en charge des langues nationales

Tri

Récupération et définition des informations de paramètres régionaux

Utilisation de la normalisation Unicode pour représenter des chaînes

Considérations relatives à la sécurité : Fonctionnalités internationales

CompareString

CompareStringEx

CompareStringOrdinal

FindNLSString

FindNLSStringEx

LCMapString

LCMapStringEx