2016-11-29 8 views
-4

Ich versuche, eine Zeichenfolge mit einer anderen Zeichenfolge zu vergleichen, und wenn sie übereinstimmen, ich möchte den Text "Das ist korrekt" zu Ausgabe, aber ich kann nicht scheinen, es funktioniert.Problem mit Vergleichen von Zeichenfolgen in C

Hier ist der Code:

int main() 
{ 
    char * password = "Torroc"; 
    char * userInput; 

    printf("Please enter your password: "); 
    scanf("%s", userInput); 

    if (strcmp(password, userInput) == 0) { 
     printf("That is correct!"); 
    } 
} 
+1

'char * userInput;' -> 'char userInput [16];' – BLUEPIXY

+1

'scanf' in einen nicht gesetzten Zeiger? Wer hat dir vorgeschlagen, das zu tun? – John3136

Antwort

2

in Ihrem Code haben userinput Zeiger nicht Vorschrift, die die Zeichenfolge zu halten, die Sie gerade mit dem Scanf Anruf zu übergeben. Sie müssen dem cstring userInput in Ihrem Stack Speicherplatz zuweisen, bevor Sie versuchen, eine Zeichenfolge zu speichern/zuzuordnen. So ...

Sie müssen den folgenden Code ändern:

char * userInput; 

zu:

char userInput[200]; 

Hier 200 ist nur ein willkürlicher Wert. In Ihrem Fall wählen Sie bitte die max. Länge der Zeichenfolge + 1 für die (\ 0).

+0

Ich habe es erklärt! – Ehsan

+0

Opps! mein Fehler, Tippfehler. – Ehsan

+0

Legen Sie auch das Limit für 'scanf()' fest, um mögliche Pufferüberläufe zu vermeiden: 'scanf ("% 199s ", userInput);' und prüfen Sie den Rückgabewert von 'scanf'. – chqrlie

1

Wenn Sie Zeichen eingeben, müssen Sie die Zeichen irgendwo speichern.

char* userInput; 

ist ein nicht initialisierter Zeiger.

Also zuerst erklären Sie ein Array für Ihre Eingabe

char userInput[128]; 

Wenn nun von der Tastatur lesen Sie die Benutzer sicherstellen müssen, nicht mehr Zeichen nicht eingeben als 127 + eine für \ 0, weil es die überschreiben würde stack so am besten zu lesen von der Tastatur ist die Verwendung von fgets, es ist auch gut, um den Rückgabewert zu überprüfen, wenn der Benutzer einfach auf ENTER gedrückt, ohne etwas zu schreiben fgets gibt NULL zurück.

if (fgets(userInput, sizeof(userInput), stdin) != NULL) { 

Jetzt haben Sie die Zeichenfolge, die der Benutzer eingegeben hat, plus das Ende der Zeile Zeichen. Um es zu entfernen können Sie etwas tun, wie

char* p = strchr(userInput,'\n'); 
    if (p != NULL) *p = '\0'; 

Jetzt können Sie die Saiten vergleichen

if (strcmp(password, userInput) == 0) { 
     puts("That is correct!"); 
    } 
+0

Beachten Sie, dass 'scanf ("% s ", userInput)' eine andere Semantik als 'fgets()' hat. 'scanf' mit einem '% s'-Format liest ein durch Leerzeichen getrenntes Wort. 'fgets' liest eine ganze Zeile. Der OP muss entscheiden, was er will. (Normalerweise sollten Passwörter Whitespace enthalten dürfen, aber das ist ein Problem mit dem Anwendungsverhalten, kein C-Problem.) Etwas wie 'scanf ("% 20s ", userInput)' kann einen Pufferüberlauf vermeiden. –

+0

@KeithThompson Ich finde fgets einfacher zu verwenden, Sie können immer sscanf auf das Ergebnis verwenden, wenn mehr Parsing Power benötigt wird –

+0

Ein anderes Idiom zum Zappen einer neuen Zeile ist 'userInput [strcspn (userInput," \ n ")] = '\ 0' ; '. –

0

Wenn Sie darüber nachdenken, „a string“ in C, sollten Sie es als ein Array von char ‚s sehen .

 0 1 2 3 4 5   9 
    +---+---+---+---+---+---+-- --+---+ 
s -> | p | i | p | p | o | \0| ... | | 
    +---+---+---+---+---+---+-- --+---+ 

ist, was

char s[10] = "pippo"; 

schaffen würde:

mir die Kennung s statt userInput der Kürze halber verwenden lassen.

Mit anderen Worten, es ist ein Speicherblock, in dem die ersten 6 Bytes wie gezeigt initialisiert wurden. Es gibt keine sVariable überall.

Stattdessen erklärt ein char * wie in

char *s; 

würde eine Variable erstellen, die einen Zeiger auf char halten kann:

+------------+ 
s| 0xCF024408 |  <-- represent an address 
    +------------+ 

Wenn Sie so denken, fällt sofort das zu tun:

scanf("%s",s); 

machen nur Sinn in der fi ersten Fall, wo es (hoffentlich) genug Speicher gibt, um die Zeichenfolge zu halten.

Im zweiten Fall zeigt die Variable s auf eine zufällige Adresse und Sie schreiben etwas in einen unbekannten Speicherbereich.

Für Vollständigkeit, in Fällen wie:

char *s = "pippo"; 

haben Sie die folgende Situation in Erinnerung:

    0 1 2 3 4 5 
       +---+---+---+---+---+---+  Somewhere in the 
    0x0B320080 | p | i | p | p | o | \0| <-- readonly portion 
       +---+---+---+---+---+---+  of memory 


    +------------+  a variable pointing 
s| 0x0B320080 | <-- to the address where 
    +------------+  the string is 

Sie können s woanders machen zeigen, aber sie können nicht den Inhalt der Änderung String zeigt von s.

Verwandte Themen