2010-05-24 12 views
53

Jaka jest różnica między memcpy() i strcpy()? Próbowałem go znaleźć za pomocą programu, ale oba dają ten sam wynik.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; 
} 

wyjścia

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

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

Odpowiedz

92

co można zrobić, aby zobaczyć ten efekt

skompilować i uruchomić ten kod:

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

To będzie produkować ten wynik:

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

Widać, że "ch" zostało skopiowane przez memcpy(), ale nie strcpy().

+1

Dziękuję bardzo za jasne wyjaśnienie. –

+1

Witam, Wiem, że post jest stary, ale mam dwa pytania dotyczące tego. Po pierwsze - 'printf ("% 2.2x ", * p);' - dlaczego ograniczyłeś printf do wersji 2.2? Poza tym nie widzę wcale kropki ... Drugi - 'printf ("% c ", * p? * P: '');' - co ten test naprawdę sprawdza? Jeśli '* p'? Dziękuję z góry za Twoją odpowiedź! –

+7

W instrukcji printf "x" oznacza "base 16". "2.2" oznacza: dwie i tylko dwie cyfry. Test '* p' oznacza:" jeśli null zostanie naciśnięty, wydrukuj spację. " – egrunin

52

strcpy przystanki po napotkaniu null, memcpy nie. Nie widać tutaj efektu, ponieważ %s w printf również zatrzymuje się na NULL.

+0

następnie co można zrobić, aby zobaczyć ten efekt –

+2

@ Sachin: Inicjalizuj 'p' i' t' na coś (wszystkie puste pola, na przykład), a następnie po skopiowaniu porównaj 'p [3]' do 't [3]'. 'Strcpy' nie wykracza poza' p [2] ', gdzie znalazł znak null, ale' memcpy' zgodnie z poleceniem skopiował pięć znaków. – Cascabel

+8

Drobne wybieranie nitów: strcpy zatrzymuje się, gdy napotka znak NUL (jeden "L"). NULL (dwa "L" s) jest stałą czasu kompilacji dla wskaźnika gwarantowanego, że nie wskaże żadnego poprawnego obiektu. –

2

Główna różnica polega na tym, że memcpy() zawsze kopiuje dokładnie określoną liczbę bajtów; Natomiast strcpy() skopiuje, dopóki nie odczyta bajtu NUL (aka 0), a następnie zatrzyma się po tym.

3

Z powodu znaku pustego w twoim ciągu, printf nie pokaże niczego poza tym. Różnica między p i t będzie występować w postaciach 4 i 5. p nie będzie żadnych (będą to śmieci), a t będzie miało litery "c" i "h".

12

strcpy kończy się, gdy zostanie znaleziony zerowy łańcuch znaków. memcpy wymaga podania parametru wielkości. W przypadku, gdy przedstawiłeś, że instrukcja printf jest zatrzymywana po znalezieniu terminatora o wartości NULL dla obu tablic znaków, jednak możesz zauważyć, że t[3] i t[4] również skopiowały w nich dane.

9

strcpy kopiuje znak ze źródła do miejsca docelowego, jeden po drugim, aż znajdzie znak NULL lub "\ 0" w źródle.

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

gdzie jako memcpy kopii danych (znaków), a nie ze źródła do miejsca przeznaczenia danego rozmiaru n, niezależnie od danych w źródle.

memcpy Powinny być używane, jeśli wiesz, że to źródło zawiera coś innego niż znak. w przypadku zaszyfrowanych danych lub danych binarnych memcpy jest idealnym rozwiązaniem.

strcpy jest przestarzałe, więc użyj strncpy.

0
  • Zachowanie różnica: strcpy przystanki gdy napotka różnicę NULL lub '\0'
  • Osiągi: memcpy jest zwykle bardziej wydajne niż strcpy, która zawsze skanować kopiuje dane
0

problem z testu -program jest, że printf() zatrzymuje wkładania argument do %s, gdy napotka zerową rozwiązaniu \0. Więc w produkcji prawdopodobnie nie zauważył, że memcpy() skopiowane znaki c i h również.

Widziałem w GNU glibc-2.24, że (dla x86) strcpy() po prostu dzwoni memcpy(dest, src, strlen(src) + 1).

Powiązane problemy