web-dev-qa-db-de.com

C ++ Vergleichen Sie das Zeichen-Array mit dem String

Ich versuche, ein Zeichenarray mit einer Zeichenfolge wie folgt zu vergleichen:

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

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

Diese if-Anweisung wird nie als wahr bestätigt ... wenn ich var1 ausgebe, ist es "dev", ich dachte, dass es vielleicht etwas mit einer nullterminierten Zeichenfolge zu tun hat, aber die Zeichenfolgen von "dev" und var1 sind gleich ... I Dachte auch, dass var1 == "dev" "dev" mit dem Speicherort von var1 anstelle des Werts vergleicht. * var1 == "dev" führt zu einem Fehler .... hat viele Dinge ausprobiert, wahrscheinlich eine einfache Lösung für den Entwickler von saavy c ++ (ich habe c ++ in einer langen Zeit nicht codiert).

edit: wir haben es versucht

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

und

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

Vielen Dank

bearbeiten: Nach dem Testen zu Hause werde ich nur vorschlagen, dass mein Kollege den Datentyp in einen String ändert. Ich glaube, er hat ein großes Zeichen-Array mit einem String verglichen. Ich habe ein Programm zusammengestellt, das sizeof, strlen usw. ausgibt, um uns bei der Arbeit zu helfen. Vielen Dank an alle für die Hilfe.

36
Chris Klepeis

Verwenden Sie strcmp() , um den Inhalt von Zeichenfolgen zu vergleichen:

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

Erläuterung: In C ist eine Zeichenfolge ein Zeiger auf eine Speicherposition, die Bytes enthält. Das Vergleichen eines char* Mit einem char* Unter Verwendung des Gleichheitsoperators funktioniert nicht wie erwartet, da Sie die Speicherorte vergleichen der Zeichenfolgen und nicht deren Byte-Inhalt. Eine Funktion wie strcmp() durchläuft beide Zeichenfolgen und überprüft ihre Bytes, um festzustellen, ob sie gleich sind. strcmp() gibt 0 zurück, wenn sie gleich sind, und einen Wert ungleich Null, wenn sie unterschiedlich sind. Weitere Informationen finden Sie auf der Manpage .

65
John Millikin

Du arbeitest nicht mit Streichern. Sie arbeiten mit Zeigern. var1 Ist ein Zeichenzeiger (const char*). Es ist keine Zeichenfolge. Wenn es nullterminiert ist, werden bestimmte C-Funktionen behandeln es als Zeichenfolge, aber es ist im Grunde nur ein Zeiger.

Wenn Sie es also mit einem char-Array vergleichen, verwandelt sich das Array ebenfalls in einen Zeiger, und der Compiler versucht dann, eine operator == (const char*, const char*) zu finden.

Ein solcher Operator existiert. Es benötigt zwei Zeiger und gibt true zurück, wenn sie auf dieselbe Adresse verweisen. Der Compiler ruft das also auf und Ihr Code bricht ab.

WENN Sie Zeichenfolgenvergleiche durchführen möchten, müssen Sie dem Compiler mitteilen, dass Sie mit Zeichenfolgen und nicht mit Zeigern umgehen möchten.

Die C-Methode hierfür ist die Verwendung der strcmp -Funktion:

strcmp(var1, "dev");

Dies gibt Null zurück, wenn die beiden Zeichenfolgen gleich sind. (Es wird ein Wert größer als Null zurückgegeben, wenn die linke Seite lexikographisch größer als die rechte Seite ist, und ansonsten ein Wert kleiner als Null.)

Um dies zu vergleichen, müssen Sie einen der folgenden Schritte ausführen:

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

C++ hat jedoch eine sehr nützliche Klasse string. Wenn wir das benutzen, wird Ihr Code ein bisschen einfacher. Natürlich können wir aus beiden Argumenten Strings erstellen, aber wir müssen es nur mit einem von ihnen tun:

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

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

Jetzt findet der Compiler einen Vergleich zwischen String und Zeichenzeiger. Dies ist möglich, da ein Zeichenzeiger implizit in eine Zeichenfolge konvertiert werden kann, was einen Vergleich zwischen Zeichenfolge und Zeichenfolge ergibt. Und diese verhalten sich genau so, wie Sie es erwarten würden.

19
jalf

In diesem Code vergleichen Sie keine Zeichenfolgenwerte, sondern Zeigerwerte. Wenn Sie Zeichenfolgenwerte vergleichen möchten, müssen Sie eine Zeichenfolgenvergleichsfunktion wie strcmp verwenden.

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

Es gibt stabilere Funktion, wird auch das Schnurfalten los.

// 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;
    }
}

Und füge Deklaration zum Header hinzu

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

Zur Verwendung platzieren Sie einfach einen 'string_equal'-Aufruf als Bedingung für die if (oder ternäre) Anweisung/den Block.

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

Quelle: sinatramultimedia/fl32 Codec (von mir selbst geschrieben)

0

"dev" ist kein string es ist ein const char * wie var1. Sie vergleichen also tatsächlich die Speicheradressen. Da var1 Ein Zeichenzeiger ist, ist *var1 Ein einzelnes Zeichen (das erste Zeichen der Zeichenfolge, auf die verwiesen wird, um genau zu sein). Sie können ein Zeichen nicht mit einem Zeichenzeiger vergleichen, weshalb dies nicht funktioniert hat.

Da dies als c ++ markiert ist, ist es sinnvoll, std::string Anstelle von Zeichenzeigern zu verwenden, damit == wie erwartet funktioniert. (Sie müssten nur const std::string var1 Anstelle von const char *var1 Ausführen.

0
sepp2k

ihre Überlegungen zu diesem Programm weiter unten

#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

wenn Sie darüber nachdenken sollten, etwas in ein Array einzugeben, und dann strcmp-Funktionen wie das obige Programm verwenden möchten, schauen Sie sich unten ein geändertes Programm an

#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;
}

ändern Sie den Wert in "string", es wird jedoch nur 1 Eingang gelesen und der Rest wird ausgegeben. Möglicherweise werden zwei for-Schleifen und zwei Zeiger benötigt

#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