6
votes

Comparaisons de chaîne. Comment pouvez-vous comparer la chaîne avec std :: wstring? WRT STRCMP

J'essaie de comparer deux formats que je m'attendais serait quelque peu compatible, car ils sont tous deux des cordes généralement. J'ai essayé d'effectuer STRCMP avec une chaîne et STD :: wstring, et comme je suis sûr que les gourous C ++ savent, cela ne compilera tout simplement pas. Est-il possible de comparer ces deux types? Y a-t-il une conversion facile ici?


3 commentaires

Je suis confus. Essayez-vous de comparer deux chaînes larges ou essayez-vous de comparer une large chaîne à une chaîne normale?


J'ai un caractère [256] d'un filtream qui est marraillé d'un autre programme. Il faut ensuite comparer cela (il représente un nom de fichier) à un nom de fichier STD :: wstring qui est transmis comme paramètre à la fonction. Cependant, je ne peux pas comparer logiquement ces


Avez-vous des garanties concernant le codage de ces caractères? Est-ce que c'est le système local codant? Un codage connu spécifique?


4 Réponses :


2
votes

Convertissez votre wstring en une chaîne.

char c[] = "foobar";
cout<<strcmp(b.c_str(),c)<<endl;


2 commentaires

Désolé pour la réponse précédente, je l'ai changé.


Il est probable que vaut mieux aller d'une autre manière (c'est-à-dire Char * -> wstring ), car il y a moins de chance de perdre des données - vous pouvez utiliser des pointeurs bruts en chaîne comme itérateurs. Mais sinon, la méthode est la même, et l'utilisation de constructeurs est meilleur que l'autre réponse qui utilise copie . La mise en garde est la même chose: cela peut ne pas fonctionner correctement pour tous les locaux.



2
votes

Tout d'abord, vous devez vous demander pourquoi vous utilisez STD :: wstring qui est un format unicode avec char * (cstring) qui est ANSI. Il est préférable d'utiliser Unicode car il permet à votre demande d'être internationalisée, mais l'utilisation d'un mélange n'a pas beaucoup de sens dans la plupart des cas. Si vous souhaitez que vos CStrings soient unicode utilisez WCHAR_T . Si vous voulez que vos chaînes STL soient ANSI, utilisez STD :: String.

Retour à votre question.

La première chose que vous voulez faire est de convertir l'un d'entre eux pour correspondre à l'autre DataType. < / p>

std :: chaîne un std :: wstring avoir le C_STR fonction

Voici les définitions de fonction xxx

Je ne me souviens pas de la main comment Pour convertir Char * en WCHAR_T * et vice versa, mais après que vous puissiez utiliser STRCMP. Si vous google, vous trouverez un moyen.

Vous pouvez utiliser les fonctions ci-dessous pour convertir STD :: wstring à std :: string alors c_str vous donnera CHAR * que vous pouvez STRCMP < Pré> xxx


2 commentaires

Cela ne fonctionnera que si des codages multibytes et widecharar pour une locale donnée sont «compatibles» - par exemple. Si MultiByte n'est vraiment que ASCII ou Latin-1, et Widecharar est Unicode. Cela ne fonctionnera pas si MultiByte est par exemple CP1251.


C'est pourquoi j'aime Stackoverflow. Si vous allez à un résultat Google aléatoire, vous pourriez avoir la mauvaise réponse.



2
votes

La voie rapide et sale est xxx

Je dis sale car il créera une chaîne temporaire et copier votre_charne. Cependant, cela fonctionnera très bien tant que vous n'êtes pas dans une boucle serrée.

Notez que WSTSTRING utilise 16 caractères bits (c.-à-d. Unicode - 65536 caractères possibles) alors que le char * a tendance à être 8 caractères ( ASCII, anglais latin seulement). Ils ne sont pas les mêmes, alors wstring -> char * pourrait perdre une précision.

-Tom


5 commentaires

Cela semble mieux que mon idée - pour une raison quelconque, je pensais que STD :: wstring n'aurait pas les bonnes conversions. Mon approche crée deux objets supplémentaires - un nommé (et probablement plus lourd qu'un simple wstring), l'autre une instance temporaire de Wstring.


std :: wstring n'a pas de constructeur de const char * .


Vous pouvez construire un wstring de Char * Les types sous-jacents sont différents. wstring utilise WCHAR_T (qui peut être 32 octets non seulement sur certains systèmes).


Vous pouvez le construire, mais néanmoins le code tel que donné ne compilera même pas.


Yup, aurait besoin d'être std :: wstring (pcyourstring, pcyourstring + strylen (pcyourstring)) pour compiler. Ugly, mais fonctionne iff wchar_t est unicode / utf16 / utf32 et char * est ASCII ou ISO8859-1. Cela ne fonctionnera pas pour le fichier ISO-8859-15 plutôt populaire (l'€ -Vaire de l'ISO-8859)



10
votes

Vous devez convertir votre Char * String - "Multibyte" dans l'ISO C PARLANCE - à un wchar_t * chaîne - "Large caractère" dans l'ISO C. La fonction standard qui s'appelle mbstowcs ("chaîne multi-octets à une chaîne de caractères large")

note : Comme Steve a signalé dans des commentaires, il s'agit d'une fonction C99 et n'est donc pas ISO C ++ Conforme, mais peut être pris en charge par des implémentations C ++ comme extension. MSVC et G ++ le supportent tous deux.

Il est utilisé ainsi: xxx

une fois que vous avez deux wstring s, juste comparer comme d'habitude. Notez que cela utilisera le système de conversion du système actuel pour la conversion (c.-à-d. Sous Windows, ce sera le code de code «ANSI» actuel) - Normalement, il s'agit de ce que vous voulez, mais vous aurez parfois besoin de faire face à un codage spécifique, auquel cas Ce qui précède ne fera pas, et vous devrez utiliser quelque chose comme iconv .

edit

Toutes les autres réponses semble aller pour la traduction directe de CodePoint (c'est-à-dire l'équivalent de (wchar_t) C pour chaque char c dans la chaîne). Cela peut ne pas fonctionner pour tous les locaux, mais cela fonctionnera si par ex. Votre Char Toutes ASCII ou Latin-1, et votre wchar_t sont unicode. Si vous êtes sûr que c'est ce que vous voulez vraiment, le moyen le plus rapide est en fait pour éviter la conversion complètement et utiliser std :: lexicographic_compare : xxx

Si vous avez spécifiquement besoin de tester pour l'égalité, utilisez std :: égal avec une longueur de vérification: xxx


5 commentaires

Est-ce c ++? Cela semble être C99, et je ne suis pas sûr des versions de la bibliothèque C ont été fusionnées dans la norme C ++. Upvoté de toute façon - devrait travailler dans la pratique de toute façon.


Ouais, mbstowcs est C99, bien que dans la pratique, les mises en œuvre C ++, je connaisse - MSVC et G ++ - supportent cette fonction.


Il semble que l'approche 100% portable ISO C ++ serait d'utiliser le stdecvt facet et son in () méthode , mais il est tout simplement si désordonné et verbose ... msdn.microsoft.com/ FR-US / Bibliothèque / XSE90H58.ASPX - Documentation Pour cela au cas où tout le monde veut essayer d'écrire une réponse détaillée pour cela.


@Pavel - Si ce n'était pas désordonné et Verbose, qui le reconnaîtrait comme une véritable bibliothèque standard C ++?


AVERTISSEMENT: MBSTOWCS () NE COMPTEZ PAS le caractère NUL final dans le nombre de retours! Vous devriez ajouter 1 à sortie_size alors.