2012-11-06 12 views
5

Perché questo codice non funziona. Sto solo cercando di verificare se l'input dell'utente è lo stesso di una passwordstrcmp con puntatori che non funzionano in C

char *pass; 

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


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

Perché -1? Sto imparando; ho cercato di trovare la risposta qui; e per i principianti non è facile capire altre risposte. – jotape

risposta

8

In realtà non hai assegnato spazio per inserire i dati. La definizione di un puntatore definisce semplicemente una variabile che può contenere l'indirizzo di un blocco di dati, ma non alloca il blocco.

Avete un paio di opzioni, allocate la memoria dinamica dall'heap in cui scrivere e puntate il puntatore su di essa. O utilizzare la memoria allocata staticamente nello stack e passare l'indirizzo di esso alle chiamate. In questo caso, c'è un piccolo vantaggio per la memoria dinamica (perché è temporaneo in uso e piccolo). Avresti più lavoro da fare se usassi la memoria dinamica - devi assicurarti di aver ottenuto ciò che hai chiesto quando lo hai allocato e assicurarti di averlo restituito quando hai finito E assicurati di non usarlo dopo che l'hai restituito (difficile in una grande app, credimi!) È solo un lavoro in più, e non sembra che ti serva uno sforzo in più.

Gli esempi seguenti richiedono anche un controllo degli errori significativo, ma offrono un'idea generale.

ad es.

char *pass = malloc (SOMESIZE); 

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


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

o

char pass[SOMESIZE]; 

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


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

molto chiaro. Hai dimenticato il & nella seconda opzione scanf. Non ho capito perché è meglio usare la memoria dinamica (heap) rispetto alla memoria statica (stack). Quale è più piccolo? – jotape

+3

Non hai bisogno della e commerciale per la chiamata scanf perché riferirsi a un array senza alcun indice * è * l'indirizzo, cioè passa == e passa [0] – Joe

+0

@Joe ad es., Ie ie/grammer-nazi – Anthony

3

pass è un puntatore non inizializzate, e si tenta di scrivere in esso. Devi allocare abbastanza memoria per contenere una stringa. Ad esempio, char pass[SIZE] funzionerà meglio.

+0

Quindi, non devo usare un puntatore; solo una serie di caratteri? – jotape

+1

Infatti. Nota puoi anche usare l'allocazione dinamica (con un puntatore a 'char'), ma qui è inutile. – md5

1

È necessario assegnare lo pass in modo che lo scanf disponga di un luogo in cui archiviare l'input. Altrimenti si ha la corruzione della memoria.

0

Sì il puntatore non è stato inizializzato. Se esegui il debug, otterrai access violation or segmentation fault. Il codice può essere modificato come segue.

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 volevo pubblicare lo stesso, ma StackOverflow non mi permetteva di salvare modifiche <6 caratteri di cambiamento: D – anishsane

0

Non hai inizializzato pass per puntare a un buffer o in un'altra posizione per memorizzare l'ingresso.

Per qualcosa di semplice come questo, è possibile dichiarare pass come un array di char invece di un puntatore:

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

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

Tranne quando è l'operando della sizeof, _Alignof, o unari & operatori, o è una stringa letterale utilizzata per inizializzare un'altra matrice in una dichiarazione, un'espressione di tipo "Serie N-elemento di T" verrà convertita ("decadimento") in un'espressione di tipo "puntatore a T" e il valore di l'espressione sarà l'indirizzo del primo elemento dell'array.

Quando si passa pass come argomento per scanf e strcmp, il tipo di espressionepass viene convertito da "N-elemento array di char" a "puntatore a char", ed il valore dell'espressione è il indirizzo del primo elemento di pass o &pass[0].Ecco perché non è necessario utilizzare l'operatore & nella chiamata scanf.

Analogamente, nella chiamata strcmp, la stringa letterale "acopio" viene convertito da un'espressione del tipo "7-elemento array di char" (const char in C++) per "puntatore a char".

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

semplice codice per i principianti ....