comparaison entre la chaîne littérale
Ce code très simple:
#include <iostream>
using namespace std;
void exec(char* option)
{
cout << "option is " << option << endl;
if (option == "foo")
cout << "option foo";
else if (option == "bar")
cout << "opzion bar";
else
cout << "???";
cout << endl;
}
int main()
{
char opt[] = "foo";
exec(opt);
return 0;
}
générer deux avertissement: comparaison avec littéral de chaîne de résultats en non spécifiée comportement.
Pouvez-vous expliquer exactement pourquoi ce code ne fonctionne pas, mais si je change
char opt[]
à
char *opt
il fonctionne, mais génère de l'avertissement? Est-ce lié à l' \0 résiliation? Quelle est la différence entre les deux déclaration de l'opt? Que faire si j'utilise const qualificatif? La solution est d'utiliser std::string?
L'un des quelques doublons: stackoverflow.com/questions/1997778/...
Lorsque tu fais if (option == "toto")", vous êtes niot de la comparaison de deux chaînes de caractères -- vous êtes de la comparaison de deux les pointeurs
Lorsque tu fais if (option == "toto")", vous êtes niot de la comparaison de deux chaînes de caractères -- vous êtes de la comparaison de deux les pointeurs
OriginalL'auteur Ruggero Turra | 2010-03-18
Vous devez vous connecter pour publier un commentaire.
des tableaux de char ou de char pointeurs ne sont pas vraiment la même chose que les objets de la classe string en C++, donc ce
Ne pas comparer la chaîne
option
de la chaîne littérale "foo", il compare les adresse deoption
avec l'adresse de la chaîne littérale "foo". Vous devez utiliser l'une des nombreuses fonctions de comparaison des chaînes si vous voulez savoir si l'option est la même que "foo".strcmp
est le moyen le plus évident pour ce faire, ou vous pouvez utiliserstd::string
au lieu dechar*
Il ne "marche" pas parce que vous avez déclaré comme char*, mais parce que vous avez attribué à le point à la chaîne littérale "foo". Puis plus tard lorsque vous comparez cela à la lettre "foo", l'adresse sera la même si le compilateur a combiné les deux "foo"s Compilateurs souvent de reconnaître que vous avez utilisé la même chaîne de caractères littérale en deux endroits et ont tous deux se réfèrent à la même littérale, mais qui ne marchera pas dans le cas général.
Dans le cas où il n'est pas assez clair à partir de John commentaire,
char x[] = "..."
crée un bloc contigu dechar
s dans la mémoire et copie le contenu, tandis quechar * x ="..."
crée un seul pointeur et assigne l'adresse de l'littérale.OriginalL'auteur John Knoeller
Vous pouvez utiliser
==
opérateur pour comparer des chaînes uniquement si vous utilisezstd::string
(qui est une bonne pratique). Si vous utilisez de style C char*/char[] les chaînes, vous devez utiliser les fonctions Cstrcmp
oustrncmp
.Vous pouvez également utiliser le
std::string::operator ==
de comparerstd::string
avec une chaîne C:if (std::string(option) == "toto"), j'ai édité réponse pour cela.
Pourquoi voulez-vous travailler avec char* au lieu de string, mais pas inclure les fonctions de cstring?
Vous êtes de droite. En général je n'aime pas utiliser des librairies en c, en c++, donc je vais passer à std::string. Je voulais utiliser char* dans les paramètres de ne pas changer la signature de la fonction.
OriginalL'auteur Laurynas Biveinis
La raison pour laquelle il n'a pas de travail est parce que la comparaison ne permet pas de comparer des chaînes de caractères, mais le caractère des pointeurs.
La raison pour laquelle il peut de travail lorsque vous utilisez char*, c'est parce que le compilateur peut décider de stocker la chaîne littérale "opt" une fois et de le réutiliser pour les deux références (je suis sûr d'avoir vu un compilateur paramètre quelque part qui indique si le compilateur ne ce).
Dans le cas de l'omble opt[], le compilateur copie la chaîne de caractères littérale de la zone de stockage réservé pour l'opt array (probablement sur la pile), ce qui provoque les pointeurs pour être différent.
Renze
OriginalL'auteur Renze de Waal
Vous ressemble est venu de Java/C# 🙂 En C++ string est juste un pointeur vers la mémoire où les caractères sont stockés et avec null char à la fin. Si les chaînes de "look" de l'égalité, ils peuvent pointer vers différentes zones de la mémoire et ne sera pas égale. pour vérifier l'égalité soit utiliser C++de la classe std::string ou C de la fonction strcmp .
==
est incorrect car il compare uniquement les références et de ne pas les cordes. Puis à nouveau, en Java, une seule copie de chaque littéral de chaîne est gardé en mémoire, de sorte que la comparaison de deux chaînes de caractères les références à la même littéral de travailler (comme si vous utilisezchar *
au lieu dechar []
en C/C++ avec les compilateurs qui suppression des doublons de littéraux)Ok, donc Java pas. En C# str == "tsa" appelle str.Equals("tsa"), car il est la surcharge d'opérateur
OriginalL'auteur Andrey
Pour le C++ je voudrais utiliser les std::string solution:
std::string sait comment créer de lui-même hors de char[], char*, etc, de sorte que vous pouvez toujours appeler la fonction de ces moyens.
OriginalL'auteur Bill