char array1[18] = {"abcdefg"};ist kein richtiges char-Array.
Aragaer
Verwenden Sie die Funktion strcpy (array2, array1)
Rohan
1
Während es als char-Array funktioniert (funktioniert zufällig), sollte es entweder als char array1[18] = "abcdefg";oderchar array1[18] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', '\0'};
aragaer
13
@aragaer 6.7.9 (14): "Ein Array vom Zeichentyp kann durch ein Zeichenfolgenliteral oder ein UTF-8-Zeichenfolgenliteral initialisiert werden, das optional in geschweiften Klammern eingeschlossen ist ." char array1[18] = {"abcdefg"};ist ungewöhnlich, aber 100% pukka.
Daniel Fischer
Antworten:
82
Sie können dies nicht direkt tun array2 = array1, da Sie in diesem Fall die Adressen der Arrays ( char *) und nicht deren innere Werte ( char) bearbeiten .
Konzeptionell möchten Sie alle Zeichen Ihrer Quelle ( Array1 ) durchlaufen und in das Ziel ( Array2 ) kopieren . Es gibt verschiedene Möglichkeiten, dies zu tun. Zum Beispiel könnten Sie eine einfache for-Schleife schreiben oder verwenden memcpy.
Die empfohlene Methode für Zeichenfolgen ist jedoch die Verwendung strncpy. Es verhindert häufige Fehler, die beispielsweise zu Pufferüberläufen führen (was besonders gefährlich ist, wenn array1sie durch Benutzereingaben gefüllt werden: Tastatur, Netzwerk usw.). Wie so:
// Will copy 18 characters from array1 to array2strncpy(array2, array1, 18);
Als @Prof. Falken in einem Kommentar erwähnt, strncpykann böse sein . Stellen Sie sicher, dass Ihr Zielpuffer groß genug ist, um den Quellpuffer zu enthalten (einschließlich des \0am Ende der Zeichenfolge).
warum können wir nicht einfach array2 = array1 machen?
user2131316
2
@ user2131316: Dies liegt an der Art und Weise, wie Array-Namen semantisch in Zeigerwerte konvertiert werden. Ich erkläre dies in meiner Antwort.
jxh
Es hat mich verwirrt, dass Sie erwähnen array1=array2, was impliziert, dass array1 den neuen Wert erhält, aber Ihr Code macht es umgekehrt. Nur für den Fall, dass jemand anderes darauf hereinfällt.
Lucidbrot
33
Wenn Ihre Arrays keine String-Arrays sind, verwenden Sie:
memcpy(array2, array1, sizeof(array2));
Das erste Argument von memcpy ist das Zielarray, das array2 sein sollte!
Bert Regelink
Würde sizeof () nicht die Größe des Zeigers zurückgeben (dh die Wortgröße auf Ihrem Computer)?
Wecherowski
1
@Wecherowski: Wenn Sie ein Array an eine Funktion übergeben, wird es zu einem Zeiger. Innerhalb dieser Funktion können Sie dann nicht sizeof()die Größe des Arrays bestimmen. Ansonsten sizeof()funktioniert gut für diese Aufgabe.
Bugfinger
26
Wenn Sie sich vor nicht terminierten Zeichenfolgen schützen möchten, die alle möglichen Probleme verursachen können, kopieren Sie Ihre Zeichenfolge wie folgt:
Diese letzte Zeile ist eigentlich wichtig, da strncpy()sie nicht immer mit Null endet Zeichenfolgen . (Wenn der Zielpuffer zu klein ist, um die gesamte Quellzeichenfolge zu enthalten, beendet sntrcpy () die Zielzeichenfolge nicht mit Null.)
In der Manpage für strncpy () heißt es sogar: "Warnung: Wenn unter den ersten n Bytes von src kein Nullbyte vorhanden ist, wird die in dest platzierte Zeichenfolge nicht nullterminiert."
Der Grund, warum sich strncpy () so seltsam verhält, ist, 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:
Wenn Ihre Arrays an eine Funktion übergeben werden, können Sie sie anscheinend zuweisen, dies ist jedoch nur ein Zufall der Semantik. In C zerfällt ein Array in einen Zeigertyp mit dem Wert der Adresse des ersten Mitglieds des Arrays, und dieser Zeiger wird übergeben. Ihr Array-Parameter in Ihrer Funktion ist also wirklich nur ein Zeiger. Die Zuordnung ist nur eine Zeigerzuweisung:
Das Array selbst bleibt nach der Rückkehr von der Funktion unverändert.
Diese Semantik "Zerfall auf 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 Zuordnung 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 */
Um herauszufinden, warum die Semantik "Zerfall in Zeigerwert" eingeführt wurde, sollte eine Quellcode-Kompatibilität mit dem Vorgänger von C erreicht werden. Weitere Informationen finden Sie unter Die Entwicklung der C-Sprache .
Ihre cstringcpyFunktion beendet das Zielarray nicht mit Null.
Chqrlie
habe es nicht verstanden. Bitte geben Sie Ihren "Fix" an.
Boris
@ zett42: Beachten Sie, dass diese cstringcpyFunktion strcpymit denselben Mängeln fast genau semantisch äquivalent ist , nämlich keine Überprüfung auf Pufferüberlauf.
Chqrlie
2
Ich empfehle, memcpy () zum Kopieren von Daten zu verwenden. Auch wenn wir einen Puffer einem anderen als zuweisen array2 = array1, haben beide Arrays den gleichen Speicher und jede Änderung in arrary1 wird auch in Array2 abgelenkt. Aber wir verwenden memcpy, beide Puffer haben unterschiedliche Arrays. Ich empfehle memcpy (), da strcpy und die zugehörige Funktion kein NULL-Zeichen kopieren.
c Funktionen nur unten ... c ++ Sie müssen ein char-Array ausführen, dann eine Zeichenfolgenkopie verwenden und dann die Zeichenfolgen-Tokenizor-Funktionen verwenden ... c ++ hat es sehr viel schwieriger gemacht, irgendetwas zu tun
#include<iostream>#include<fstream>#include<cstring>#define TRUE 1#define FALSE 0typedefint Bool;
usingnamespacestd;
Bool PalTrueFalse(char str[]);
intmain(void){
charstring[1000], ch;
int i = 0;
cout<<"Enter a message: ";
while((ch = getchar()) != '\n') //grab users input string untill
{ //Enter is pressedif (!isspace(ch) && !ispunct(ch)) //Cstring functions checking for
{ //spaces and punctuations of all kindsstring[i] = tolower(ch);
i++;
}
}
string[i] = '\0'; //hitting null deliminator once users inputcout<<"Your string: "<<string<<endl;
if(PalTrueFalse(string)) //the string[i] user input is passed after//being cleaned into the null function.cout<<"is a "<<"Palindrome\n"<<endl;
elsecout<<"Not a palindrome\n"<<endl;
return0;
}
Bool PalTrueFalse(char str[]){
int left = 0;
int right = strlen(str)-1;
while (left<right)
{
if(str[left] != str[right]) //comparing most outer values of stringreturn FALSE; //to inner values.
left++;
right--;
}
return TRUE;
}
#include<string.h> int array1[10] = {0,1,2,3,4,5,6,7,8,9};
int array2[10];
memcpy(array2,array1,sizeof(array1)); // memcpy("destination","source","size")
Das wird nicht kompiliert. Verwenden Sie int array1[10] = {0,1,2,3,4,5,6,7,8,9};stattdessen.
Tim
0
Sie können keine Arrays zum Kopieren zuweisen. Wie Sie den Inhalt eines in einen anderen kopieren können, hängt von mehreren Faktoren ab:
charWenn Sie für Arrays wissen, dass das Quellarray nullterminiert ist und das Zielarray groß genug für die Zeichenfolge im Quellarray ist, einschließlich des Nullterminators, verwenden Sie strcpy():
Wenn Sie nicht wissen, ob das Zielarray groß genug ist, die Quelle jedoch eine C-Zeichenfolge ist und das Ziel eine richtige C-Zeichenfolge sein soll, verwenden Sie snprinf():
#include<stdio.h>char array1[] = "a longer string that might not fit";
char array2[18];
...
snprintf(array2, sizeof array2, "%s", array1);
Wenn das Quellarray nicht unbedingt nullterminiert ist, Sie jedoch wissen, dass beide Arrays dieselbe Größe haben, können Sie Folgendes verwenden memcpy:
#include<string.h>char array1[28] = "a non null terminated string";
char array2[28];
...
memcpy(array2, array1, sizeof array2);
Keines der oben genannten hat bei mir funktioniert .. das funktioniert namehier perfekt
, char *namewas über die Funktion übergeben wird
Holen Sie sich die char *nameNutzungsdauerstrlen(name)
Das Speichern in einer const-Variablen ist wichtig
Erstellen Sie ein charArray mit der gleichen Länge
Kopieren Sie nameden Inhalt zu tempverwendenstrcpy(temp, name);
Verwenden Sie, wie Sie möchten, wenn Sie den ursprünglichen Inhalt zurückhaben möchten. Kopiertemp strcpy(name, temp);zurück nach nameund voila funktioniert perfekt
strcpy
odermemcpy
.char array1[18] = {"abcdefg"};
ist kein richtiges char-Array.char array1[18] = "abcdefg";
oderchar array1[18] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', '\0'};
char array1[18] = {"abcdefg"};
ist ungewöhnlich, aber 100% pukka.Antworten:
Sie können dies nicht direkt tun
array2 = array1
, da Sie in diesem Fall die Adressen der Arrays (char *
) und nicht deren innere Werte (char
) bearbeiten .Konzeptionell möchten Sie alle Zeichen Ihrer Quelle ( Array1 ) durchlaufen und in das Ziel ( Array2 ) kopieren . Es gibt verschiedene Möglichkeiten, dies zu tun. Zum Beispiel könnten Sie eine einfache for-Schleife schreiben oder verwenden
memcpy
.Die empfohlene Methode für Zeichenfolgen ist jedoch die Verwendung
strncpy
. Es verhindert häufige Fehler, die beispielsweise zu Pufferüberläufen führen (was besonders gefährlich ist, wennarray1
sie durch Benutzereingaben gefüllt werden: Tastatur, Netzwerk usw.). Wie so:// Will copy 18 characters from array1 to array2 strncpy(array2, array1, 18);
Als @Prof. Falken in einem Kommentar erwähnt,
strncpy
kann böse sein . Stellen Sie sicher, dass Ihr Zielpuffer groß genug ist, um den Quellpuffer zu enthalten (einschließlich des\0
am Ende der Zeichenfolge).quelle
array1=array2
, was impliziert, dass array1 den neuen Wert erhält, aber Ihr Code macht es umgekehrt. Nur für den Fall, dass jemand anderes darauf hereinfällt.Wenn Ihre Arrays keine String-Arrays sind, verwenden Sie:
memcpy(array2, array1, sizeof(array2));
quelle
sizeof()
die Größe des Arrays bestimmen. Ansonstensizeof()
funktioniert gut für diese Aufgabe.Wenn Sie sich vor nicht terminierten 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 eigentlich wichtig, da
strncpy()
sie nicht immer mit Null endet Zeichenfolgen . (Wenn der Zielpuffer zu klein ist, um die gesamte Quellzeichenfolge zu enthalten, beendet sntrcpy () die Zielzeichenfolge nicht mit Null.)In der Manpage für strncpy () heißt es sogar: "Warnung: Wenn unter den ersten n Bytes von src kein Nullbyte vorhanden ist, wird die in dest platzierte Zeichenfolge nicht nullterminiert."
Der Grund, warum sich strncpy () so seltsam verhält, ist, 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.)
quelle
snprintf()
das Problemstrncpy()
nicht besteht.Sie können keine Arrays zuweisen, die Namen sind Konstanten, die nicht geändert werden können.
Sie können den Inhalt kopieren mit:
strcpy(array2, array1);
Angenommen, die Quelle ist eine gültige Zeichenfolge und das Ziel ist groß genug, wie in Ihrem Beispiel.
quelle
Wie andere angemerkt haben, werden Zeichenfolgen mit
strcpy()
oder deren Varianten kopiert . In bestimmten Fällen können Sie auch verwendensnprintf()
.Sie können Arrays im Rahmen einer Strukturzuweisung nur so zuweisen, wie Sie es möchten:
typedef struct { char a[18]; } array; array array1 = { "abcdefg" }; array array2; array2 = array1;
Wenn Ihre Arrays an eine Funktion übergeben werden, können Sie sie anscheinend zuweisen, dies ist jedoch nur ein Zufall der Semantik. In C zerfällt ein Array in einen Zeigertyp mit dem Wert der Adresse des ersten Mitglieds des Arrays, und dieser Zeiger wird übergeben. Ihr Array-Parameter in Ihrer Funktion ist also wirklich nur ein Zeiger. Die Zuordnung 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 von der Funktion unverändert.
Diese Semantik "Zerfall auf 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 Zuordnung 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 */
Um herauszufinden, warum die Semantik "Zerfall in Zeigerwert" eingeführt wurde, sollte eine Quellcode-Kompatibilität mit dem Vorgänger von C erreicht werden. Weitere Informationen finden Sie unter Die Entwicklung der C-Sprache .
quelle
array2 = array1;
nicht funktioniert. Upvote.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);
quelle
cstringcpy
Funktion beendet das Zielarray nicht mit Null.cstringcpy
Funktionstrcpy
mit denselben Mängeln fast genau semantisch äquivalent ist , nämlich keine Überprüfung auf Pufferüberlauf.Ich empfehle, memcpy () zum Kopieren von Daten zu verwenden. Auch wenn wir einen Puffer einem anderen als zuweisen
array2 = array1
, haben beide Arrays den gleichen Speicher und jede Änderung in arrary1 wird auch in Array2 abgelenkt. Aber wir verwenden memcpy, beide Puffer haben unterschiedliche Arrays. Ich empfehle memcpy (), da strcpy und die zugehörige Funktion kein NULL-Zeichen kopieren.quelle
wird in c nicht unterstützt. Sie müssen Funktionen wie strcpy () verwenden, um dies zu tun.
quelle
c Funktionen nur unten ... c ++ Sie müssen ein char-Array ausführen, dann eine Zeichenfolgenkopie verwenden und dann die Zeichenfolgen-Tokenizor-Funktionen verwenden ... c ++ hat es sehr viel schwieriger gemacht, irgendetwas zu tun
#include <iostream> #include <fstream> #include <cstring> #define TRUE 1 #define FALSE 0 typedef int Bool; using namespace std; Bool PalTrueFalse(char str[]); int main(void) { char string[1000], ch; int i = 0; cout<<"Enter a message: "; while((ch = getchar()) != '\n') //grab users input string untill { //Enter is pressed if (!isspace(ch) && !ispunct(ch)) //Cstring functions checking for { //spaces and punctuations of all kinds string[i] = tolower(ch); i++; } } string[i] = '\0'; //hitting null deliminator once users input cout<<"Your string: "<<string<<endl; if(PalTrueFalse(string)) //the string[i] user input is passed after //being cleaned into the null function. cout<<"is a "<<"Palindrome\n"<<endl; else cout<<"Not a palindrome\n"<<endl; return 0; } Bool PalTrueFalse(char str[]) { int left = 0; int right = strlen(str)-1; while (left<right) { if(str[left] != str[right]) //comparing most outer values of string return FALSE; //to inner values. left++; right--; } return TRUE; }
quelle
für ganzzahlige Typen
#include <string.h> int array1[10] = {0,1,2,3,4,5,6,7,8,9}; int array2[10]; memcpy(array2,array1,sizeof(array1)); // memcpy("destination","source","size")
quelle
int array1[10] = {0,1,2,3,4,5,6,7,8,9};
stattdessen.Sie können keine Arrays zum Kopieren zuweisen. Wie Sie den Inhalt eines in einen anderen kopieren können, hängt von mehreren Faktoren ab:
char
Wenn Sie für Arrays wissen, dass das Quellarray nullterminiert ist und das Zielarray groß genug für die Zeichenfolge im Quellarray ist, einschließlich des Nullterminators, verwenden Siestrcpy()
:#include <string.h> char array1[18] = "abcdefg"; char array2[18]; ... strcpy(array2, array1);
Wenn Sie nicht wissen, ob das Zielarray groß genug ist, die Quelle jedoch eine C-Zeichenfolge ist und das Ziel eine richtige C-Zeichenfolge sein soll, verwenden Sie
snprinf()
:#include <stdio.h> char array1[] = "a longer string that might not fit"; char array2[18]; ... snprintf(array2, sizeof array2, "%s", array1);
Wenn das Quellarray nicht unbedingt nullterminiert ist, Sie jedoch wissen, dass beide Arrays dieselbe Größe haben, können Sie Folgendes verwenden
memcpy
:#include <string.h> char array1[28] = "a non null terminated string"; char array2[28]; ... memcpy(array2, array1, sizeof array2);
quelle
Technisch gesehen können Sie ...
typedef struct { char xx[18]; } arr_wrap; char array1[18] = "abcdefg"; char array2[18]; *((arr_wrap *) array2) = *((arr_wrap *) array1); printf("%s\n", array2); /* "abcdefg" */
aber es wird nicht sehr schön aussehen.
… Es sei denn, Sie verwenden den C-Präprozessor…
#define CC_MEMCPY(DESTARR, SRCARR, ARRSIZE) \ { struct _tmparrwrap_ { char xx[ARRSIZE]; }; *((struct _tmparrwrap_ *) DESTARR) = *((struct _tmparrwrap_ *) SRCARR); }
Sie können dann tun:
char array1[18] = "abcdefg"; char array2[18]; CC_MEMCPY(array2, array1, sizeof(array1)); printf("%s\n", array2); /* "abcdefg" */
Und es funktioniert mit jedem Datentyp, nicht nur
char
:int numbers1[3] = { 1, 2, 3 }; int numbers2[3]; CC_MEMCPY(numbers2, numbers1, sizeof(numbers1)); printf("%d - %d - %d\n", numbers2[0], numbers2[1], numbers2[2]); /* "abcdefg" */
(Ja, über der Code gewährt , um Arbeit immer und es ist tragbar)
quelle
Keines der oben genannten hat bei mir funktioniert .. das funktioniert
name
hier perfekt ,char *name
was über die Funktion übergeben wirdchar *name
Nutzungsdauerstrlen(name)
char
Array mit der gleichen Längename
den Inhalt zutemp
verwendenstrcpy(temp, name);
Verwenden Sie, wie Sie möchten, wenn Sie den ursprünglichen Inhalt zurückhaben möchten. Kopiertemp
strcpy(name, temp);
zurück nachname
und voila funktioniert perfektconst int size = strlen(name); char temp[size]; cout << size << endl; strcpy(temp, name);
quelle