2012-11-06 15 views
5

Warum dieser Code nicht funktioniert. Ich versuche nur, wenn die Benutzereingabe das gleiche wie ein Passwortstrcmp mit Zeigern funktioniert nicht in C

char *pass; 

printf("Write the password: "); 
scanf("%s", pass); // Because is a pointer the & is out ? 


if(strcmp(pass , "acopio") == 0) 
+4

Warum -1? Ich lerne; versuchte hier die Antwort zu finden; und für Anfänger ist es nicht leicht, andere Antworten zu verstehen. – jotape

Antwort

8

Sie haben tatsächlich keinen Speicherplatz für die Bereitstellung von Daten zugewiesen. Das Definieren eines Zeigers definiert nur eine Variable, die die Adresse eines Datenblocks enthalten kann, sie weist den Block nicht zu.

Sie haben ein paar Optionen, ordnen Sie dynamischen Speicher aus dem Heap zu schreiben und den Zeiger darauf zeigen. Oder verwenden Sie statisch zugewiesenen Speicher auf dem Stack und übergeben Sie die Adresse an Ihre Anrufe. In diesem Fall hat der dynamische Speicher wenig Vorteile (da er temporär verwendet wird und klein ist). Sie hätten mehr zu tun, wenn Sie dynamischen Speicher verwenden würden - Sie müssen sicherstellen, dass Sie das bekommen haben, wonach Sie gefragt haben, wenn Sie es zugewiesen haben, und sicherstellen, dass Sie es zurückgegeben haben, wenn Sie fertig sind UND stellen Sie sicher, dass Sie es nicht verwenden nachdem du es zurück gegeben hast (tricky in einer großen App, vertrau mir!) Es ist nur mehr Arbeit, und du scheinst diese zusätzliche Anstrengung nicht zu brauchen.

Die folgenden Beispiele würden ebenfalls eine signifikante Fehlerprüfung erfordern, geben Ihnen jedoch die allgemeine Idee.

z.B.

char *pass = malloc (SOMESIZE); 

printf("Write the password: "); 
scanf("%s", pass); 


if(strcmp(pass , "acopio") == 0) 

oder

char pass[SOMESIZE]; 

printf("Write the password: "); 
scanf("%s", pass); 


if(strcmp(pass , "acopio") == 0) 
+0

sehr klar. Sie haben die & in den 2. Optionen scanf vergessen. Warum ist es besser, dynamischen Speicher (Heap) als statischen Speicher (Stack) zu verwenden? Was ist kleiner? – jotape

+3

Sie benötigen das kaufmännische Und-Zeichen für den Scanf-Aufruf nicht, da ein Verweis auf ein Array ohne Index * die Adresse ist, dh pass == & pass [0] – Joe

+0

@Joe zB nicht ie/gramer-nazi – Anthony

3

pass ist ein unitialized Zeiger ist zu überprüfen, und Sie versuchen, in sie zu schreiben. Sie müssen genügend Speicher reservieren, um eine Zeichenfolge zu speichern. Zum Beispiel wird char pass[SIZE] besser funktionieren.

+0

Also brauche ich keinen Zeiger; nur ein Array von Char? – jotape

+1

In der Tat. Beachten Sie, dass Sie auch die dynamische Zuweisung (mit einem Zeiger auf "char") verwenden können, aber hier ist es nutzlos. – md5

1

Sie müssen die pass zuweisen, so dass die scanf einen Platz zum Speichern der Eingabe haben wird. Andernfalls haben Sie Speicherbeschädigung.

0

Ja der Zeiger wurde nicht initialisiert. Wenn Sie es debuggen, erhalten Sie eine access violation or segmentation fault. Der Code kann wie folgt geändert werden.

char pass[22];//22 can be replaced with other number 

    printf("Write the password: "); 
    scanf("%s", pass); 
    if(strcmp(pass , "acopio") == 0) 
    printf("fu");//just to check 
+0

@Daveshaw: I wollte das gleiche posten, aber stackoverflow würde mir nicht erlauben, Änderungen <6 Zeichen der Änderung zu speichern: D – anishsane

0

Sie haben nicht pass zu einem Puffer oder einem anderen Ort Punkt initialisiert, um die Eingabe zu speichern.

Für einfache etwas wie dieses, können Sie pass als ein Array von char anstelle eines Zeigers erklären:

char pass[N]; // where N is large enough to hold the password plus a 0 terminator 

scanf("%s", pass); 
if (strcmp(pass, "acopio") == 0) 
{ 
    ... 
} 

Außer, wenn es der Operand des sizeof, _Alignof oder einstellige & Operatoren oder ist Wird ein String-Literal verwendet, um ein anderes Array in einer Deklaration zu initialisieren, wird ein Ausdruck vom Typ "N-Element-Array von T" in einen Ausdruck vom Typ "Zeiger auf T" konvertiert ("Decay"), und der Wert von der Ausdruck wird die Adresse der sein erstes Element des Arrays.

Wenn Sie passieren pass als Argument an scanf und strcmp, die Art des Ausdruckpass von „N-Element-Array von char“ umgewandelt wird zu „Zeiger auf char“, und der Wert des Ausdrucks ist der Adresse des ersten Elements von pass oder &pass[0].Aus diesem Grund müssen Sie den Operator & nicht im scanf-Aufruf verwenden.

Ähnlich wird in dem strcmp Anrufs, die Stringliteral "acopio" wird aus einem Ausdruck des Typs "7-Element-Array von char" (const char in C++) auf "Zeiger auf char" umgewandelt.

0
#include<stdio.h> 
main() 
{ 
    int mystrcmp(char *,char *); 

    char s1[100],s2[100]; 
    char *p1,*p2; 
    p1=s1; 
    p2=s2; 
    printf("Enter the first string..?\n"); 
    scanf("%s",p1); 
    printf("Enter the second string..?\n"); 
    scanf("%s",p2); 
    int x=mystrcmp(p1,p2); 
    if(x==0) 
     printf("Strings are same\n"); 
    else 
     printf("Strings are not same..\n"); 


} 
int mystrcmp(char *p1,char *p2) 
{ 
    while(*p1==*p2) 
    { 
     if(*p1=='\0' || *p2=='\0') 
      break; 
     p1++; 
     p2++; 
    } 
    if(*p1=='\0' &&as *p2=='\0') 
     return(0); 
    else 
     return(1); 
} 

einfacher Code für Anfänger ....