web-dev-qa-db-fra.com

C ++ Compare un tableau de caractères avec une chaîne

J'essaie de comparer un tableau de caractères avec une chaîne comme ceci:

const char *var1 = " ";
var1 = getenv("myEnvVar");

if(var1 == "dev")
{
   // do stuff
}

Cette instruction if ne valide jamais comme vraie ... lorsque je produis var1, c'est "dev", je pensais que cela avait peut-être quelque chose à voir avec une chaîne terminée par null, mais le strlen de "dev" et var1 sont égaux ... I pensait aussi que var1 == "dev" comparait "dev" à l'emplacement de mémoire de var1 au lieu de la valeur. * var1 == "dev" entraîne une erreur .... a essayé beaucoup de choses, probablement une solution simple pour le développeur saavy c ++ (je n'ai pas codé c ++ dans un temps très long).

edit: nous avons essayé

if(strcmp(var1, "dev") == 0)

et

if(strncmp(var1, "dev", 3) == 0)

Merci

edit: Après avoir testé à la maison, je vais juste suggérer à mon collègue de changer le type de données en chaîne. Je crois qu'il comparait un tableau de caractères d'une grande taille à une chaîne. J'ai mis en place un programme qui génère sizeof, strlen, etc. pour nous aider à le résoudre. Merci à tous pour l'aide.

36
Chris Klepeis

Utilisez strcmp() pour comparer le contenu des chaînes:

if (strcmp(var1, "dev") == 0) {
}

Explication: en C, une chaîne est un pointeur vers un emplacement mémoire qui contient des octets. La comparaison d'un char* À un char* À l'aide de l'opérateur d'égalité ne fonctionnera pas comme prévu, car vous comparez les emplacements de mémoire des chaînes plutôt que de leur contenu en octets. Une fonction telle que strcmp() parcourra les deux chaînes, vérifiant leurs octets pour voir s'ils sont égaux. strcmp() renverra 0 si elles sont égales et une valeur non nulle si elles diffèrent. Pour plus de détails, consultez la page de manuel .

65
John Millikin

Vous ne travaillez pas avec des chaînes. Vous travaillez avec des pointeurs. var1 Est un pointeur de caractère (const char*). Ce n'est pas une chaîne. Si elle est terminée par un caractère nul, alors certaines fonctions C le traiteront comme une chaîne, mais ce n'est fondamentalement qu'un pointeur.

Ainsi, lorsque vous le comparez à un tableau de caractères, le tableau se désintègre également en un pointeur et le compilateur essaie ensuite de trouver une operator == (const char*, const char*).

Un tel opérateur existe. Il prend deux pointeurs et renvoie true s'ils pointent vers la même adresse. Ainsi, le compilateur invoque cela et votre code se casse.

SI vous voulez faire des comparaisons de chaînes, vous devez dire au compilateur que vous voulez traiter chaînes, pas pointeurs.

La façon C de le faire est d'utiliser la fonction strcmp:

strcmp(var1, "dev");

Cela retournera zéro si les deux chaînes sont égales. (Il renverra une valeur supérieure à zéro si le côté gauche est lexicographiquement supérieur au côté droit, et une valeur inférieure à zéro dans le cas contraire.)

Donc, pour comparer l'égalité, vous devez effectuer l'une des opérations suivantes:

if (!strcmp(var1, "dev")){...}
if (strcmp(var1, "dev") == 0) {...}

Cependant, C++ possède une classe string très utile. Si nous utilisons cela, votre code devient un peu plus simple. Bien sûr, nous pourrions créer des chaînes à partir des deux arguments, mais nous n'avons qu'à le faire avec l'un d'eux:

std::string var1 = getenv("myEnvVar");

if(var1 == "dev")
{
   // do stuff
}

Maintenant, le compilateur rencontre une comparaison entre la chaîne et le pointeur char. Il peut gérer cela, car un pointeur char peut être implicitement converti en chaîne, produisant une comparaison chaîne/chaîne. Et ceux-ci se comportent exactement comme vous vous en doutez.

19
jalf

Dans ce code, vous ne comparez pas des valeurs de chaîne, vous comparez des valeurs de pointeur. Si vous souhaitez comparer des valeurs de chaîne, vous devez utiliser une fonction de comparaison de chaînes telle que strcmp.

if ( 0 == strcmp(var1, "dev")) {
  ..
}
1
JaredPar

Il y a une fonction plus stable, se débarrasse également du pliage des cordes.

// Add to C++ source
bool string_equal (const char* arg0, const char* arg1)
{
    /*
     * This function wraps string comparison with string pointers
     * (and also works around 'string folding', as I said).
     * Converts pointers to std::string
     * for make use of string equality operator (==).
     * Parameters use 'const' for prevent possible object corruption.
     */
    std::string var0 = (std::string) arg0;
    std::string var1 = (std::string) arg1;
    if (var0 == var1)
    {
        return true;
    }
    else
    {
        return false;
    }
}

Et ajoutez une déclaration à l'en-tête

// Parameters use 'const' for prevent possible object corruption.
bool string_equal (const char* arg0, const char* arg1);

Pour l'utilisation, il suffit de placer un appel 'string_equal' comme condition de l'instruction if (ou ternaire)/bloc.

if (string_equal (var1, "dev"))
{
    // It is equal, do what needed here.
}
else
{
    // It is not equal, do what needed here (optional).
}

Source: codec sinatramultimedia/fl32 (il est écrit par moi-même)

0
AraneaSerket6848

"dev" n'est pas un string c'est un const char * comme var1. Vous comparez ainsi en effet les adresses mémoire. Étant que var1 est un pointeur de caractère, *var1 est un seul caractère (le premier caractère de la séquence de caractères pointée pour être précis). Vous ne pouvez pas comparer un caractère à un pointeur de caractère, c'est pourquoi cela n'a pas fonctionné.

Étant donné que cela est marqué comme c ++, il serait judicieux d'utiliser std::string au lieu de pointeurs char, ce qui ferait fonctionner == comme prévu. (Il vous suffirait de faire const std::string var1 au lieu de const char *var1.

0
sepp2k

votre avis sur ce programme ci-dessous

#include <stdio.h>
#include <string.h>

int main ()
{
char str[][5] = { "R2D2" , "C3PO" , "R2A6" };
int n;
puts ("Looking for R2 astromech droids...");
for (n=0 ; n<3 ; n++)
if (strncmp (str[n],"R2xx",2) == 0)
{
  printf ("found %s\n",str[n]);
}
return 0;
}
//outputs:
//
//Looking for R2 astromech droids...
//found R2D2
//found R2A6

quand vous devriez penser à entrer quelque chose dans un tableau puis utiliser des fonctions strcmp comme le programme ci-dessus ... consultez un programme modifié ci-dessous

#include <iostream>
#include<cctype>
#include <string.h>
#include <string>
using namespace std;

int main()
{
int Students=2;
int Projects=3, Avg2=0, Sum2=0, SumT2=0, AvgT2=0, i=0, j=0;
int Grades[Students][Projects];

for(int j=0; j<=Projects-1; j++){
  for(int i=0; i<=Students; i++) {
 cout <<"Please give grade of student "<< j <<"in project "<< i  <<  ":";
  cin >> Grades[j][i];

  }
  Sum2 = Sum2 + Grades[i][j];
     Avg2 = Sum2/Students;
}
SumT2 = SumT2 + Avg2;
AvgT2 = SumT2/Projects;
cout << "avg is  : " << AvgT2 << " and sum : " << SumT2 << ":";
return 0;
}

changer en chaîne sauf qu'il ne lit qu'une entrée et jette le reste peut-être besoin de deux pour les boucles et deux pointeurs

#include <cstring>
#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
int main()
{
char name[100];
//string userInput[26];
int i=0, n=0, m=0;
cout<<"your name? ";
cin>>name;
cout<<"Hello "<<name<< endl;

char *ptr=name;
for (i = 0; i < 20; i++)
{
cout<<i<<" "<<ptr[i]<<" "<<(int)ptr[i]<<endl;
}   
int length = 0;
while(name[length] != '\0')
{
length++;
}
                    for(n=0; n<4; n++)
                {
                            if (strncmp(ptr, "snit", 4) == 0)
                            {
            cout << "you found the snitch "    <<        ptr[i];
                            }
                }
cout<<name <<"is"<<length<<"chars long";
}
0
101dolmations