C++ Compare char array avec string

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

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

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

cette instruction if ne valide jamais comme vraie... quand je sors var1 c'est" dev", je pensais que peut-être ça avait quelque chose à voir avec une chaîne terminée nulle, mais les strlen de" dev " et var1 sont égaux... J'ai aussi pensé que peut-être var1 == "dev" comparait "dev" avec l'emplacement mémoire de var1 au lieu de la valeur. * var1 = = " dev " se traduit par une erreur.... essayé beaucoup de choses, probablement une solution simple pour le développeur saavy c++ (Je n'ai pas codé c++ dans un temps assez long).

modifier: nous avons essayé

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

et

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

Merci

edit: après des tests à 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 grande taille à une corde. J'ai mis en place un programme qui produit sizeof, strlen, etc pour nous aider à travailler à travers elle. Merci à tous pour l'aide.

30
demandé sur Chris Klepeis 2009-08-25 23:51:09

6 réponses

Utiliser 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 de mémoire qui contient des octets. La comparaison d'un char*char* utiliser l'opérateur d'égalité ne fonctionnera pas comme prévu, parce que vous comparez le emplacements de mémoire des chaînes plutôt que de leur contenu en octets. Une fonction telle que strcmp() va itérer à travers les deux chaînes, en vérifiant leurs octets pour voir s'ils sont égaux. strcmp() renvoie 0 s'ils sont égaux, et une valeur non nulle s'ils diffèrent. Pour plus de détails, voir man.

60
répondu John Millikin 2009-08-25 19:52:54

Vous ne travaillez pas avec des chaînes. Tu travailles avec des pointeurs. var1 est un pointeur de char (const char*). Il n'est pas une chaîne. Si c'est null, alors certaines fonctions C sera traiter comme une chaîne de caractères, mais il est fondamentalement juste un pointeur.

Donc quand vous le comparez à un char, la baie se désintègre à un pointeur, et le compilateur essaie alors de trouver un operator == (const char*, const char*).

un tel opérateur existe. Il faut deux pointeurs et retourne true s'ils pointent vers la même adresse. Donc le compilateur l'invoque, et votre code casse.

SI vous voulez faire des comparaisons de chaînes, vous devrez indiquer au compilateur que vous voulez traiter avec chaînes de caractères, pas les pointeurs.

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

strcmp(var1, "dev");

ceci retournera zéro si les deux chaînes sont égal. (Il retournera une valeur supérieure à zéro si côté gauche est lexicographiquement plus grand que le côté droit, et une valeur inférieure à zéro sinon.)

Donc, pour comparer pour l'égalité, vous avez besoin de faire un:

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

cependant, C++ a un string classe. Si nous l'utilisons, 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 besoin de le faire qu'avec l'un d'eux:

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

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

maintenant le compilateur rencontre une comparaison entre string et char pointeur. Il peut gérer cela, parce qu'un pointeur de char peut être implicitement converti en une chaîne, ce qui donne une comparaison chaîne/chaîne. Et ceux-là se comportent exactement comme on s'y attendrait.

16
répondu jalf 2009-08-26 11:46:02

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

if ( 0 == strcmp(var1, "dev")) {
  ..
}
1
répondu JaredPar 2009-08-25 19:53:23

"dev" n'est pas un string c'est un const char *var1. Ainsi vous comparez en effet les adresses de mémoire. Être que var1 est un pointeur de char, *var1 est un caractère unique (le premier caractère de la séquence pointé vers le caractère pour être précis). On ne peut pas comparer un char avec un pointeur de char, c'est pourquoi ça n'a pas marché.

c'est marqué que c++, il serait judicieux d'utiliser std::string au lieu des pointeurs de char, ce qui ferait == fonctionner comme prévu. (Vous n' suffit de faire const std::string var1 au lieu de const char *var1.

0
répondu sepp2k 2009-08-25 20:00:48

il y a une fonction plus stable, qui élimine aussi le repliement 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 ajouter déclaration à en-tête

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

pour l'usage, il suffit de placer un appel 'string_equal' comme condition de IF (ou ternary) statement/block.

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

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

0
répondu AraneaSerket6848 2015-09-04 17:26:31

votre façon de penser à propos de 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 et puis utiliser les 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 de chaîne, sauf qu'elle ne lit 1 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] != '')
{
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
répondu 101dolmations 2016-10-06 18:42:59