2010-05-24 17 views
53

Qual è la differenza tra memcpy() e strcpy()? Ho provato a trovarlo con l'aiuto di un programma, ma entrambi stanno dando lo stesso risultato.strcpy vs. memcpy

int main() 
{ 
    char s[5]={'s','a','\0','c','h'}; 
    char p[5]; 
    char t[5]; 
    strcpy(p,s); 
    memcpy(t,s,5); 
    printf("sachin p is [%s], t is [%s]",p,t); 
    return 0; 
} 

uscita

sachin p is [sa], t is [sa] 
+1

Vedere http://stackoverflow.com/questions/2884874/when-to-use-strncpy-or-memmove –

risposta

92

cosa si potrebbe fare per vedere questo effetto

Compilare ed eseguire questo codice:

void dump5(char *str); 

int main() 
{ 
    char s[5]={'s','a','\0','c','h'}; 

    char membuff[5]; 
    char strbuff[5]; 
    memset(membuff, 0, 5); // init both buffers to nulls 
    memset(strbuff, 0, 5); 

    strcpy(strbuff,s); 
    memcpy(membuff,s,5); 

    dump5(membuff); // show what happened 
    dump5(strbuff); 

    return 0; 
} 

void dump5(char *str) 
{ 
    char *p = str; 
    for (int n = 0; n < 5; ++n) 
    { 
     printf("%2.2x ", *p); 
     ++p; 
    } 

    printf("\t"); 

    p = str; 
    for (int n = 0; n < 5; ++n) 
    { 
     printf("%c", *p ? *p : ' '); 
     ++p; 
    } 

    printf("\n", str); 
} 

Si produrrà questo output:

73 61 00 63 68 sa ch 
73 61 00 00 00 sa 

Si può vedere che la "ch" è stata copiata da memcpy(), ma non da strcpy().

+1

Grazie mille per la chiara spiegazione. –

+1

Ciao, so che il post è vecchio, ma ho due domande a riguardo. Prima - 'printf ("% 2.2x ", * p);' - perché hai limitato printf a 2.2? Inoltre posso vedere NESSUN punto affatto ... Secondo - 'printf ("% c ", * p? * P: '');' - cosa controlla veramente questo test? Se '* p'? Grazie in anticipo per la risposta! –

+7

In un'istruzione printf, "x" significa "base 16". "2.2" significa: due e solo due cifre. Il test '* p' significa:" se si preme un nullo, si stampa uno spazio ". – egrunin

52

strcpy ferma quando incontra un NULL, memcpy no. Non vedi l'effetto qui, poiché %s in printf si ferma anche su NULL.

+0

quindi cosa si può fare per vedere questo effetto –

+2

@Sachin: Inizializza 'p' e' t' su qualcosa (tutti gli spazi vuoti, per esempio), quindi dopo aver copiato, confronta 'p [3]' in 't [3]'. 'Strcpy' non andava oltre' p [2] ', dove trovava il carattere null, ma la' memcpy' come diretta copiava cinque caratteri. – Cascabel

+8

Nit-pick secondario: strcpy si ferma quando incontra il carattere NUL (una "L"). NULL (due "L") è una costante in fase di compilazione per un puntatore garantito che non punta a nessun oggetto valido. –

2

La differenza principale è che memcpy() copia sempre il numero esatto di byte specificato; strcpy(), d'altra parte, copierà fino a quando non leggerà un byte NUL (aka 0), e poi si fermerà dopo.

3

A causa del carattere nullo nella stringa s, il printf non mostrerà nulla oltre. La differenza tra p e t sarà nei caratteri 4 e 5. p non ne avrà (saranno spazzatura) e t avrà 'c' e 'h'.

12

strcpy termina quando viene trovato il terminatore nullo della stringa di origine. memcpy richiede che venga passato un parametro di dimensione. Nel caso in cui sia stata presentata l'istruzione printf dopo l'individuazione del terminatore nullo per entrambi gli array di caratteri, tuttavia si troverà t[3] e t[4] in cui sono stati copiati anche i dati.

9

strcpy copia il carattere dall'origine alla destinazione uno alla volta finché non trova NULL o il carattere '\ 0' nella sorgente.

while((*dst++) = (*src++)); 

dove come memcpy dati copia (non caratteri) dall'origine alla destinazione di data dimensione n, indipendentemente dati sorgente.

memcpy deve essere utilizzato se si conosce bene che la fonte contiene diverso da carattere. per dati crittografati o dati binari, memcpy è la soluzione ideale.

strcpy obsoleto, quindi utilizzare strncpy.

0
  • Comportamento differenza: strcpy fermate quando si incontra una differenza NULL o '\0'
  • Performance: memcpy di solito è più efficiente di strcpy, che sempre la scansione dei dati viene copiato
0

Il problema con il test -programma è, che il printf() interrompe l'inserimento dell'argomento in %s, quando incontra una terminazione nulla \0. Quindi, probabilmente non hai notato nell'output che memcpy() ha copiato i caratteri c e h.

Ho visto in GNU glibc-2.24, che (per x86) strcpy() chiama solo memcpy(dest, src, strlen(src) + 1).