Was ist der Unterschied zwischen memcpy()
und strcpy()
? Ich habe versucht, es mit Hilfe eines Programms zu finden, aber beide geben die gleiche Ausgabe.
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;
}
Ausgabe
sachin p is [sa], t is [sa]
Antworten:
Kompilieren Sie diesen Code und führen Sie ihn aus:
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); }
Es wird diese Ausgabe erzeugen:
73 61 00 63 68 sa ch 73 61 00 00 00 sa
Sie können sehen, dass das "ch" von kopiert wurde
memcpy()
, aber nichtstrcpy()
.quelle
printf("%2.2x ", *p);
- warum haben Sie printf auf 2.2 beschränkt? Außerdem kann ich KEINEN Punkt sehen ... Zweitens -printf("%c", *p ? *p : ' ');
- was prüft dieser Test wirklich? Wenn*p
? Vielen Dank im Voraus für Ihre Antwort!*p
Test bedeutet: "Wenn Sie eine Null treffen, drucken Sie ein Leerzeichen."strcpy
stoppt, wenn es auf ein NUL ('\0'
) - Zeichenmemcpy
trifft, nicht. Sie sehen den Effekt hier nicht, da%s
printf auch bei NUL stoppt.quelle
p
undt
zu etwas (alle Rohlinge, zum Beispiel), dann nach dem Kopieren, zu vergleichen ,p[3]
zut[3]
. Dasstrcpy
ging nicht darüber hinausp[2]
, wo es das Nullzeichen fand, sondern dasmemcpy
wie angegeben fünf Zeichen kopierte.strcpy
Wird beendet, wenn der Nullterminator der Quellzeichenfolge gefunden wird.memcpy
erfordert die Übergabe eines Größenparameters. In dem von Ihnen präsentierten Fall wird dieprintf
Anweisung angehalten, nachdem der Nullterminator für beide Zeichenarrays gefunden wurde. Sie werden jedoch auch Daten darin findent[3]
undt[4]
kopiert haben.quelle
strcpy
Kopiert das Zeichen nacheinander von der Quelle zum Ziel, bis es in der Quelle das Zeichen NULL oder '\ 0' findet.while((*dst++) = (*src++));
Dabei werden
memcpy
Daten (nicht Zeichen) von der Quelle zum Ziel der angegebenen Größe n kopiert, unabhängig von den Daten in der Quelle.memcpy
sollte verwendet werden, wenn Sie gut wissen, dass die Quelle andere als Zeichen enthält. Für verschlüsselte oder binäre Daten ist memcpy der ideale Weg.strcpy
ist veraltet, also verwendenstrncpy
.quelle
Aufgrund des Nullzeichens in Ihrer
s
Zeichenfolgeprintf
wird darüber hinaus nichts angezeigt. Der Unterschied zwischenp
undt
wird in den Zeichen 4 und 5 sein. Siep
werden keine haben (sie werden Müll sein) undt
werden das'c'
und haben'h'
.quelle
strcpy
stoppt, wenn es auf einNULL
oder trifft'\0'
memcpy
Regel effizienter als dasstrcpy
, bei dem immer die kopierten Daten gescannt werdenquelle
Der Hauptunterschied besteht darin, dass
memcpy()
immer die genaue Anzahl der von Ihnen angegebenen Bytes kopiert wird.strcpy()
Auf der anderen Seite wird kopiert, bis ein NUL-Byte (auch bekannt als 0) gelesen wird, und danach angehalten.quelle
Das Problem mit Ihrem Testprogramm ist, dass das
printf()
Einfügen des Arguments beendet wird%s
, wenn eine Nullterminierung auftritt\0
. Also in Ihrer Ausgabe haben Sie wahrscheinlich nicht bemerkt, dassmemcpy()
die Zeichenc
undh
auch kopiert .Ich habe in GNU gesehen
glibc-2.24
, dass (für x86)strcpy()
nur anruftmemcpy(dest, src, strlen(src) + 1)
.quelle
printf("%s",...)
stoppt das Drucken der Daten, wenn null auftritt, sodass beide Ausgaben gleich sind.Der folgende Code unterscheidet zwischen
strcpy
undmemcpy
:#include<stdio.h> #include<string.h> int main() { char s[5]={'s','a','\0','c','h'}; char p[5]; char t[5]; int i; strcpy(p,s); memcpy(t,s,5); for(i=0;i<5;i++) printf("%c",p[i]); printf("\n"); for(i=0;i<5;i++) printf("%c",t[i]); return 0; }
quelle