8
votes

Comparer des tableaux de caractères et des littéraux de chaîne en C ++

J'ai un tableau de caractères et j'essaie de comprendre s'il correspond à un littéral à chaîne, par exemple:

char value[] = "yes";
if(strcmp(value, "yes")) {
   // code block
} else {
   // code block
}


2 commentaires

Ce n'est pas ce que signifie "cstring". CSSTRING fait référence à la classe Microsoft String de MFC. Si vous voulez dire des tableaux de caractères terminés par NULL, le terme est "C chaîne" - deux mots, avec seulement le nom de la langue capitalisé.


@ROB: J'ai corrigé le titre / question pour refléter le fait qu'il demande des matrices de caractères et des littéraux à chaîne.


4 Réponses :


22
votes

std :: strcmp retourne 0 Si les chaînes sont égales.


0 commentaires

26
votes

Vérifiez la documentation pour STRCMP. Astuce: Cela ne renvoie pas une valeur booléenne.

ETA: == ne fonctionne pas en général parce que cstr1 == cstr2 compare les pointeurs , de sorte que la comparaison ne sera vraie que si CSTR1 et CSTR2 Pointez sur le même emplacement de la mémoire, même s'ils se réfèrent à des cordes qui sont lexicographiquement égales. Ce que vous avez essayé (comparer un cstring à un littéral, par exemple cstr == "oui" ) en particulier ne fonctionnera pas, car la norme n'exige pas. Dans une implémentation raisonnable, je doute que cela explose, mais cstr == "oui" est peu susceptible de réussir jamais, car cstr est peu susceptible de se référer à l'adresse de la constante de chaîne "oui" vit.


5 commentaires

+1: Le seul qui gênait d'expliquer pourquoi La première tentative de l'OP n'a pas fonctionné! Beaucoup plus important que d'expliquer quelque chose qui pourrait être trouvé dans 10 secondes en lisant la page de l'homme STRCMP (ou à googler), dans mon livre.


Pas "peu probable". Dans le code ci-dessus, la valeur ne peut avoir la même adresse que le littéral de la chaîne dans une implémentation conforme. Lorsque l'avertissement mentionne un comportement non spécifié, je suppose que cela signifie qu'il est indéterminé si le même littéral utilisé à différents endroits se retrouve avec la même adresse ou non.


@onebyone: vraiment? Je pensais que les implémentations confortables ont été autorisées à coopérer des littéraux à chaîne, de sorte que si vous aviez Char * s = "oui" ;, s == "oui" pourrait alors potentiellement être vrai.


Bien sûr, c'est le bit qui n'est pas spécifié - c'est à la mise en œuvre, que ce soit vrai ou faux. Mais dans le code de la question, valeur est un tableau, pas un pointeur. Il n'ya donc aucun moyen que son premier octet puisse légalement avoir la même adresse que le premier octet de n'importe quel littéral ou à ce sujet de tout autre objet. C'est pourquoi, quand il se dégrade à un pointeur de comparaison avec "oui", il n'est pas "peu probable" d'être égal, il n'est jamais égal.


Oh, je vois ce que tu veux dire. Oui, qu'est-ce que l'OP n'a peut-être jamais fonctionné.



3
votes

STRCMP renvoie une valeur Tri-State pour indiquer ce que sont l'ordre relatif des deux chaînes. Lors de l'appel comme STRCMP (A, B), la fonction renvoie

  • une valeur <0 quand un
  • 0 quand a == b
  • une valeur> 0 quand A> B

0 commentaires

0
votes

Comme la question est étiquetée avec David Seilers Excellente explication sur pourquoi STRCMP () n'a pas fonctionné Dans votre cas, je veux souligner, que STRCMP () ne fonctionne pas sur les tableaux de caractères en général, uniquement sur des tableaux de caractères terminés par NULL ( SOURCE ).

Dans votre cas, vous attribuez une chaîne littérale à un tableau de caractères, ce qui entraînera une Array de caractères terminé nuls automatiquement, donc aucun problème ici. Mais si vous découpez votre réseau de caractères de e. g. Un tampon, il peut ne pas être résilié de manière nuls. Dans de tels cas, il est dangereux d'utiliser strcmp () car il traversera la mémoire jusqu'à ce qu'il trouve un octet null ( '\ 0' ) pour former une chaîne. < / p>

Une autre solution à votre problème serait (en utilisant c ++ std :: string ): xxx

Ceci fonctionnera également uniquement pour Bandes de caractères terminées par NULL. Si votre matrice de caractères n'est pas désormais terminée, indiquez au constructeur std :: string Combien de temps votre tableau de caractères est le suivant: xxx


0 commentaires