wake-up-neo.net

Wie vergleiche ich Strings richtig?

Ich versuche, ein Programm zu erhalten, mit dem ein Benutzer ein Word oder Zeichen eingeben, speichern und dann drucken kann, bis der Benutzer es erneut eingibt und das Programm beendet. Mein Code sieht so aus:

#include <stdio.h>

int main()
{
    char input[40];
    char check[40];
    int i=0;
    printf("Hello!\nPlease enter a Word or character:\n");
    gets(input);
    printf("I will now repeat this until you type it back to me.\n");

    while (check != input)
    {
        printf("%s\n", input);
        gets(check); 
    }

    printf("Good bye!");


    return 0;
}

Das Problem ist, dass ich immer den Ausdruck der Eingabezeichenfolge bekomme, auch wenn die Eingabe durch den Benutzer (Überprüfung) mit dem Original (Eingabe) übereinstimmt. Vergleiche ich die beiden falsch?

152
nmagerko

Sie können Strings nicht (sinnvoll) mit != oder == vergleichen. Sie müssen strcmp verwenden:

while (strcmp(check,input) != 0)

Der Grund dafür ist, dass != und == nur die Basisadressen dieser Zeichenfolgen vergleichen. Nicht der Inhalt der Saiten.

234
Mysticial

Ok ein paar Dinge: gets ist unsicher und sollte durch fgets(input, sizeof(input), stdin) ersetzt werden, damit kein Pufferüberlauf entsteht.

Um Strings zu vergleichen, müssen Sie als Nächstes strcmp verwenden. Dabei gibt der Rückgabewert 0 an, dass die beiden Strings übereinstimmen. Bei Verwendung der Gleichheitsoperatoren (dh !=) wird die Adresse der beiden Zeichenfolgen verglichen mit den einzelnen chars in ihnen.

Beachten Sie auch, dass fgets das Zeilenvorschubzeichen '\n' auch in den Puffern speichert, obwohl es in diesem Beispiel kein Problem verursacht. gets() nicht. Wenn Sie die Benutzereingabe von fgets() mit einem Zeichenfolgenliteral wie "abc" vergleichen, würde sie niemals übereinstimmen (es sei denn, der Puffer war zu klein, so dass '\n' nicht hineinpasste).

EDIT: und erneut von dem superschnellen Mysticial geschlagen.

30
AusCBloke

Sie können Arrays nicht direkt vergleichen

array1==array2

Sie sollten sie char-by-char vergleichen; Dazu können Sie eine Funktion verwenden und einen booleschen Wert (True: 1, False: 0) zurückgeben. Dann können Sie es in der Testbedingung der while-Schleife verwenden.

Versuche dies:

#include <stdio.h>
int checker(char input[],char check[]);
int main()
{
    char input[40];
    char check[40];
    int i=0;
    printf("Hello!\nPlease enter a Word or character:\n");
    scanf("%s",input);
    printf("I will now repeat this until you type it back to me.\n");
    scanf("%s",check);

    while (!checker(input,check))
    {
        printf("%s\n", input);
        scanf("%s",check);
    }

    printf("Good bye!");

    return 0;
}

int checker(char input[],char check[])
{
    int i,result=1;
    for(i=0; input[i]!='\0' || check[i]!='\0'; i++) {
        if(input[i] != check[i]) {
            result=0;
            break;
        }
    }
    return result;
}
7
mugetsu

Verwenden Sie strcmp .

Dies ist in string.h Bibliothek und ist sehr beliebt. strcmp gibt 0 zurück, wenn die Zeichenfolgen gleich sind. Siehe this für eine bessere Erklärung, was strcmp zurückgibt.

Grundsätzlich musst du Folgendes tun:

while (strcmp(check,input) != 0)

oder

while (!strcmp(check,input))

oder 

while (strcmp(check,input))

Sie können this , ein Tutorial zu strcmp, überprüfen.

6
Ashish Ahuja

Wenn Sie versuchen, die Zeichenfolgen zu vergleichen, vergleichen Sie sie in Bezug auf die einzelnen Zeichen. Dazu können Sie eine eingebaute String-Funktion namens strcmp (input1, input2) verwenden. und Sie sollten die Header-Datei mit dem Namen #include<string.h> verwenden. 

Versuchen Sie diesen Code:

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

int main() 
{ 
    char s[]="STACKOVERFLOW";
    char s1[200];
    printf("Enter the string to be checked\n");//enter the input string
    scanf("%s",s1);
    if(strcmp(s,s1)==0)//compare both the strings  
    {
        printf("Both the Strings match\n"); 
    } 
    else
    {
        printf("Entered String does not match\n");  
    } 
    system("pause");  
} 
1

Leider können Sie strcmp nicht aus <cstring> verwenden, da dies ein C++ - Header ist und Sie ausdrücklich gesagt haben, dass es sich um eine C-Anwendung handelt. Ich hatte das gleiche Problem, also musste ich meine eigene Funktion schreiben, die strcmp implementiert:

int strcmp(char input[], char check[])
{
    for (int i = 0;; i++)
    {
        if (input[i] == '\0' && check[i] == '\0')
        {
            break;
        }
        else if (input[i] == '\0' && check[i] != '\0')
        {
            return 1;
        }
        else if (input[i] != '\0' && check[i] == '\0')
        {
            return -1;
        }
        else if (input[i] > check[i])
        {
            return 1;
        }
        else if (input[i] < check[i])
        {
            return -1;
        }
        else
        {
            // characters are the same - continue and check next
        }
    }
    return 0;
}

Ich hoffe, dass dir das gut tut.

0
Steztric
    #include<stdio.h>
    #include<string.h>
    int main()
    {
        char s1[50],s2[50];
        printf("Enter the character of strings: ");
        gets(s1);
        printf("\nEnter different character of string to repeat: \n");
        while(strcmp(s1,s2))
        {
            printf("%s\n",s1);
            gets(s2);
        }
        return 0;
    }

Dies ist eine sehr einfache Lösung, bei der Sie Ihre Ausgabe nach Belieben erhalten.

0
Rupani T D

Wie vergleiche ich Strings richtig?

char input[40];
char check[40];
strcpy(input, "Hello"); // input assigned somehow
strcpy(check, "Hello"); // check assigned somehow

// insufficient
while (check != input)

// good
while (strcmp(check, input) != 0)
// or 
while (strcmp(check, input))

Lassen Sie uns tiefer gehen, um zu sehen , warum check != input Nicht ausreicht .

In C ist string eine Standard-Bibliotheksspezifikation.

Ein string ist eine zusammenhängende Folge von Zeichen, die mit dem ersten Nullzeichen abgeschlossen sind und dieses enthalten.
C11 §7.1.1 1

input ist kein string. input ist Array 40 von char .

Der Inhalt von input kann zu string werden.

Wenn ein Array in einem Ausdruck verwendet wird, wird es in den meisten Fällen in die Adresse seines ersten Elements konvertiert.

Das Folgende konvertiert check und input in ihre jeweiligen Adressen des ersten Elements, dann werden diese Adressen verglichen.

check != input   // Compare addresses, not the contents of what addresses reference

Um strings zu vergleichen, müssen wir diese Adressen verwenden und uns dann die Daten ansehen, auf die sie verweisen.
strcmp() erledigt den Job . §7.23.4.2

int strcmp(const char *s1, const char *s2);

Die Funktion strcmp vergleicht den String, auf den s1 Zeigt, mit dem String, auf den s2 Zeigt.

Die Funktion strcmp gibt eine Ganzzahl zurück, die größer, gleich oder kleiner als Null ist, entsprechend, wenn die Zeichenfolge, auf die s1 Zeigt, größer, gleich oder kleiner als die Zeichenfolge ist, auf die von gezeigt wird s2.

Der Code kann nicht nur feststellen, ob die Zeichenfolgen dieselben Daten enthalten, sondern auch, welche größer/kleiner sind, wenn sie sich unterscheiden.

Das Folgende ist wahr, wenn sich die Zeichenfolge unterscheidet.

strcmp(check, input) != 0

Weitere Informationen finden Sie unter Eigene strcmp() -Funktion erstellen

0
chux

Willkommen beim Konzept des pointer. Generationen von Programmieranfängern haben das Konzept für schwer fassbar gehalten. Wenn Sie jedoch zu einem kompetenten Programmierer heranwachsen möchten, müssen Sie dieses Konzept meistern - und außerdem fragen Sie bereits die richtige Frage. Das ist gut.

Ist Ihnen klar, was eine Adresse ist? Siehe dieses Diagramm:

----------     ----------
| 0x4000 |     | 0x4004 |
|    1   |     |    7   |
----------     ----------

In dem Diagramm wird die Ganzzahl 1 unter Adresse 0x4000 gespeichert. Warum bei einer Adresse? Weil der Speicher groß ist und viele Zahlen speichern kann, da eine Stadt groß ist und viele Familien aufnehmen kann. Jede ganze Zahl wird an einem Speicherort gespeichert, da sich jede Familie in einem Haus befindet. Jeder Speicherplatz wird durch ein address, identifiziert, da jedes Haus durch eine Adresse identifiziert wird.

Die zwei Kästchen im Diagramm repräsentieren zwei unterschiedliche Speicherplätze. Man kann sich sie als Häuser vorstellen. Die ganze Zahl 1 befindet sich im Speicherbereich an der Adresse 0x4000 (denken Sie "4000 Elm St."). Die ganze Zahl 7 befindet sich im Speicherplatz an der Adresse 0x4004 (denken Sie "4004 Elm St.").

Sie dachten, Ihr Programm würde die 1 mit der 7 vergleichen, war es aber nicht. Es wurde das 0x4000 mit dem 0x4004 verglichen. Was passiert also, wenn Sie diese Situation haben?

----------     ----------
| 0x4000 |     | 0x4004 |
|    1   |     |    1   |
----------     ----------

Die zwei ganzen Zahlen sind gleich, aber die Adressen unterscheiden sich. Ihr Programm vergleicht die Adressen.

0
thb

Ich mag die Antwort, die als beste ausgewählt wurde, außer dass ich strcmp() nicht mag. Stattdessen sollten Sie strncmp() in Verbindung mit Makros verwenden. Hier ist also Ihr Code mit kleinen Verbesserungen.

#include <stdio.h>

#define MAXLEN 40
int main()
{
    char input[MAXLEN];
    char check[MAXLEN];
    int i=0;
    printf("Hello!\nPlease enter a Word or character:\n");
    gets(input);
    printf("I will now repeat this until you type it back to me.\n");

    while (strcmp(check, input))
    {
        printf("%s\n", input);
        gets(check); 
    }

    printf("Good bye!");


    return 0;
}

Und hier ist, warum strncmp():

#include <stdio.h>

#define MAXLEN 40
int main()
{
    char input[MAXLEN];
    char check[MAXLEN];
    int i=0;
    printf("Hello!\nPlease enter a Word or character:\n");
    gets(input);
    int len = strlen(input);
    for (; i < 10000; ++i)
        input [len - 2 + i] = 'A';

    printf("I will now repeat this until you type it back to me.\n");

    while (strncmp(check, input, MAXLEN))
    {
        printf("%s\n", input);
        gets(check); 
    }

    printf("Good bye!");


    return 0;
}
0
Gox