In C habe ich zwei Char-Arrays:
char array1[18] = "abcdefg";
char array2[18];
So kopieren Sie den Wert von array1
zu array2
? Kann ich das einfach machen: array2 = array1
?
Benutzer2131316
In C habe ich zwei Char-Arrays:
char array1[18] = "abcdefg";
char array2[18];
So kopieren Sie den Wert von array1
zu array2
? Kann ich das einfach machen: array2 = array1
?
aymericbeaumet
Sie können nicht direkt tun array2 = array1
denn in diesem Fall manipuliert man die Adressen der Arrays (char *
) und nicht von ihren inneren Werten (char
).
Was Sie konzeptionell tun möchten, ist, alle Zeichen Ihrer Quelle zu durchlaufen (Reihe1) und kopieren Sie sie an das Ziel (Reihe2). Dazu gibt es mehrere Möglichkeiten. Sie könnten zum Beispiel eine einfache for-Schleife schreiben oder verwenden memcpy
.
Davon abgesehen ist die empfohlene Methode für Zeichenfolgen die Verwendung strncpy
. Es verhindert häufige Fehler, die z. Pufferüberläufe (was besonders gefährlich ist, wenn array1
wird aus Benutzereingaben gefüllt: Tastatur, Netzwerk usw.). So:
// Will copy 18 characters from array1 to array2
strncpy(array2, array1, 18);
Als @Prof. Falken erwähnte in einem Kommentar, strncpy
kann böse sein. Stellen Sie sicher, dass Ihr Zielpuffer groß genug ist, um den Quellpuffer (einschließlich der \0
am Ende der Zeichenfolge).
blogs.msdn.com/b/michael_howard/archive/2004/11/02/251296.aspx strncpy() ist eigentlich auch böse. Siehe auch stackoverflow.com/questions/2114896/…
– Prof. Falken
20. Mai 2013 um 8:44 Uhr
warum können wir nicht einfach array2 = array1 machen?
– Benutzer2131316
20. Mai 2013 um 9:08 Uhr
@ user2131316: Dies liegt an der Art und Weise, wie Array-Namen semantisch in Zeigerwerte umgewandelt werden. Ich erkläre dies in meiner Antwort.
– jxh
20. Mai 2013 um 9:23 Uhr
Es hat mich verwirrt, dass du es erwähnst array1=array2
, was impliziert, dass array1 den neuen Wert erhält, aber Ihr Code macht es umgekehrt. Nur für den Fall, dass noch jemand darauf reinfällt.
– Klarbrot
6. April 2017 um 9:47 Uhr
strncat würde immer ein nullterminiertes Ergebnis ohne Pufferüberlauf liefern. Sieh dir das an.
– Louis Go
25. November 2020 um 7:07 Uhr
kAmol
Wenn Ihre Arrays keine String-Arrays sind, verwenden Sie:
memcpy(array2, array1, sizeof(array2));
Würde sizeof() nicht die Größe des Zeigers zurückgeben (dh die Wortgröße auf Ihrem Computer)?
– Wechselowski
24. November 2019 um 10:10 Uhr
@Wecherowski: Wenn Sie ein Array an eine Funktion übergeben, wird es zu einem Zeiger degradiert. Innerhalb dieser Funktion können Sie nicht verwenden sizeof()
um dann die Größe des Arrays zu bestimmen. Andernfalls sizeof()
funktioniert gut für diese Aufgabe.
– Benutzer6214440
30. März 2020 um 15:01 Uhr
Prof. Falken
Wenn Sie sich vor nicht abgeschlossenen Zeichenfolgen schützen möchten, die alle möglichen Probleme verursachen können, kopieren Sie Ihre Zeichenfolge wie folgt:
char array1[18] = {"abcdefg"};
char array2[18];
size_t destination_size = sizeof (array2);
strncpy(array2, array1, destination_size);
array2[destination_size - 1] = '\0';
Diese letzte Zeile ist tatsächlich wichtig, weil strncpy()
nicht immer null beenden Saiten. (Wenn der Zielpuffer zu klein ist, um die gesamte Quellzeichenfolge aufzunehmen, beendet sntrcpy() die Zielzeichenfolge nicht mit Null.)
Die Manpage für strncpy() gibt sogar an “Warnung: Wenn sich unter den ersten n Bytes von src kein Null-Byte befindet, wird die in dest platzierte Zeichenfolge nicht mit Null abgeschlossen.”
Der Grund, warum sich strncpy() auf diese etwas seltsame Weise verhält, liegt darin, dass es ursprünglich nicht als sichere Methode zum Kopieren von Zeichenfolgen gedacht war.
Eine andere Möglichkeit besteht darin, snprintf() als sicheren Ersatz für strcpy() zu verwenden:
snprintf(array2, destination_size, "%s", array1);
(Danke jxh für den Tipp.)
Beachten Sie, dass snprintf()
habe das problem nicht strncpy()
tut.
– jxh
20. Mai 2013 um 8:58 Uhr
Erzeugt das nicht eine Warnung? strncpy akzeptiert const char als Quelle.
– kon psych
19. September 2015 um 20:05 Uhr
@konpsych das sollte keine Warnung generieren.
– Prof. Falken
19. September 2015 um 21:49 Uhr
@Rahav, snprintf() ist einfacher richtig zu verwenden als strncpy()
– Prof. Falken
27. Juni um 20:58 Uhr
@Rahav, ohne Testen unmöglich zu sagen, aber a) Diese Operationen sind auf moderner Hardware sowieso schnell. b) Für sehr kleine Strings könnte strncpy() vielleicht schneller sein, für größere Strings dominiert das tatsächliche Kopieren im Speicher die benötigte Zeit und beide sollten ungefähr gleich schnell sein, denke ich. Die heutigen Compiler und Bibliotheken sind auch unglaublich im Optimieren und was früher schwer zu erraten war, ist jetzt sehr, sehr schwer zu erraten. Messen / profilieren Sie einfach, wenn Sie sicher sein wollen. Im tatsächlichen Gebrauch wird es fast nie einen bedeutenden Unterschied geben, ist meine beste Vermutung.
– Prof. Falken
28. Juni um 11:09 Uhr
jxh
Wie andere angemerkt haben, werden Zeichenfolgen mit kopiert strcpy()
oder seine Varianten. In bestimmten Fällen könnten Sie verwenden snprintf()
auch.
Sie können Arrays nur im Rahmen einer Strukturzuweisung beliebig zuweisen:
typedef struct { char a[18]; } array;
array array1 = { "abcdefg" };
array array2;
array2 = array1;
Wenn Ihre Arrays an eine Funktion übergeben werden, scheint es, dass Sie sie zuweisen dürfen, aber dies ist nur ein Zufall der Semantik. In C zerfällt ein Array zu einem Zeigertyp mit dem Wert der Adresse des ersten Elements des Arrays, und dieser Zeiger wird übergeben. Ihr Array-Parameter in Ihrer Funktion ist also wirklich nur ein Zeiger. Die Zuweisung ist nur eine Zeigerzuweisung:
void foo (char x[10], char y[10]) {
x = y; /* pointer assignment! */
puts(x);
}
Das Array selbst bleibt nach der Rückkehr aus der Funktion unverändert.
Diese Semantik vom “Abklingen zum Zeigerwert” für Arrays ist der Grund dafür, dass die Zuweisung nicht funktioniert. Der l-Wert hat den Array-Typ, aber der r-Wert ist der verfallene Zeigertyp, sodass die Zuweisung zwischen inkompatiblen Typen erfolgt.
char array1[18] = "abcdefg";
char array2[18];
array2 = array1; /* fails because array1 becomes a pointer type,
but array2 is still an array type */
Warum die “Decay to Pointer Value”-Semantik eingeführt wurde, um eine Kompatibilität des Quellcodes mit dem Vorgänger von C zu erreichen, können Sie nachlesen Die Entwicklung der C-Sprache für Details.
Sie können Arrays nicht zuweisen, die Namen sind Konstanten, die nicht geändert werden können.
Sie können die kopieren Inhaltmit:
strcpy(array2, array1);
Angenommen, die Quelle ist eine gültige Zeichenfolge und das Ziel ist groß genug, wie in Ihrem Beispiel.
zett42
es sollte so aussehen:
void cstringcpy(char *src, char * dest)
{
while (*src) {
*(dest++) = *(src++);
}
*dest="\0";
}
.....
char src[6] = "Hello";
char dest[6];
cstringcpy(src, dest);
Achil
Ich empfehle memcpy() zum Kopieren von Daten zu verwenden. Auch wenn wir einem anderen as einen Puffer zuweisen array2 = array1
, beide Arrays haben denselben Speicher und jede Änderung in Array1 wird auch in Array2 abgelenkt. Aber wir verwenden memcpy, beide Puffer haben unterschiedliche Arrays. Ich empfehle memcpy(), da strcpy und verwandte Funktionen kein NULL-Zeichen kopieren.
strcpy
odermemcpy
.– Alok Speichern
20. Mai 2013 um 8:38 Uhr
char array1[18] = {"abcdefg"};
ist kein richtiges char-Array.– Aragaer
20. Mai 2013 um 8:39 Uhr
Verwenden Sie die Funktion strcpy (array2, array1).
– Rohan
20. Mai 2013 um 8:40 Uhr
Während es als char-Array funktioniert (funktioniert zufällig), sollte es entweder als deklariert werden
char array1[18] = "abcdefg";
oderchar array1[18] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', '\0'};
– Aragaer
20. Mai 2013 um 8:43 Uhr
@aragaer 6.7.9 (14): “Ein Array des Zeichentyps kann durch ein Zeichenkettenliteral oder UTF−8-Stringliteral initialisiert werden, optional in geschweiften Klammern eingeschlossen.”
char array1[18] = {"abcdefg"};
ist ungewöhnlich, aber 100% pukka.– Daniel Fischer
20. Mai 2013 um 10:19 Uhr