Zuweisen von Zeichenketten zu Arrays von Zeichen

Lesezeit: 4 Minuten

Rees Benutzer-Avatar
Ree

Etwas verwundert bin ich über folgendes.

Beispiel 1:

char s[100] = "abcd"; // declare and initialize - WORKS

Beispiel 2:

char s[100]; // declare
s = "hello"; // initalize - DOESN'T WORK ('lvalue required' error)

Ich frage mich, warum der zweite Ansatz nicht funktioniert. Es scheint natürlich, dass es sollte (es funktioniert mit anderen Datentypen)? Kann mir jemand die Logik dahinter erklären?

Benutzeravatar von shoosh
tschüss

Beim Initialisieren eines Arrays erlaubt Ihnen C, es mit Werten zu füllen. So

char s[100] = "abcd";

ist im Grunde dasselbe wie

int s[3] = { 1, 2, 3 };

aber es erlaubt Ihnen nicht, die Aufgabe seitdem zu erledigen s ist ein Array und kein freier Zeiger. Die Bedeutung von

s = "abcd" 

ist, dem Zeiger den Wert von zuzuweisen abcd zu s aber du kannst dich nicht ändern s seitdem zeigt nichts mehr auf das Array.
Dies kann und funktioniert, wenn s ist ein char* – ein Zeiger, der auf alles zeigen kann.

Wenn Sie die Zeichenfolge kopieren möchten, verwenden Sie einfach strcpy.

  • Gute Antwort, außer Sie sollten nie mehr normales strcpy verwenden. Verwenden Sie strncpy oder strlcpy.

    – dwc

    23. Februar 2009 um 23:01 Uhr

  • Außerdem sollte s const char* sein, nicht char*.

    – Aib

    24. Februar 2009 um 14:17 Uhr

  • s[0] = 'x'; s[1] = 'y'; s[2] = 'z'; s[3] = 'm'; funktioniert, wenn man die Zeichenfolgenzeichen auch nach der Initialisierung einzeln ersetzen möchte.

    – RBT

    28. Oktober 2016 um 2:44 Uhr


  • @RBT, vielleicht funktioniert es auf Ihrer Plattform mit Ihren Kompilierungsflags, aber oft werden diese Zeichenfolgen im Nur-Lese-Speicher definiert. das Schreiben darauf würde einen Segfault oder einen Access-Violation-Fehler verursachen

    – tschüss

    4. Dezember 2016 um 7:52 Uhr

  • @dwc es gibt kein Problem mit strcpy(), stellen Sie einfach sicher, dass Ihr Puffer lang genug für die Eingabezeichenfolge ist

    – 12431234123412341234123

    18. Januar 2017 um 10:16 Uhr


Benutzeravatar von dwc
dwc

In C gibt es so etwas wie einen “String” nicht. In C sind Strings eindimensionale Arrays von charabgeschlossen durch ein Nullzeichen \0. Da Sie in C keine Arrays zuweisen können, können Sie auch keine Zeichenfolgen zuweisen. Das wörtliche „Hallo“ ist syntaktischer Zucker für const char x[] = {'h','e','l','l','o','\0'};

Der richtige Weg wäre:

char s[100];
strncpy(s, "hello", 100);

oder noch besser:

#define STRMAX 100
char    s[STRMAX];
size_t  len;
len = strncpy(s, "hello", STRMAX);

  • Nicht die empfohlene Vorgehensweise. Hüten Sie sich vor den Kuriositäten von strncpy: stackoverflow.com/a/1258577/2974922

    – Nukleon

    23. Februar 2017 um 10:40 Uhr


  • Ich denke, dieser Ansatz könnte leicht empfohlen werden

    – Volt

    12. Oktober 2018 um 8:00 Uhr

Initialisierung und Zuweisung sind zwei unterschiedliche Operationen, die hier denselben Operator (“=”) verwenden.

Benutzeravatar von Matt Davis
Matt Davis

1    char s[100];
2    s = "hello";

In dem von Ihnen bereitgestellten Beispiel wird s tatsächlich in Zeile 1 initialisiert, nicht in Zeile 2. Auch wenn Sie ihm an dieser Stelle keinen expliziten Wert zugewiesen haben, hat der Compiler dies getan.

In Zeile 2 führen Sie eine Zuweisungsoperation durch, und Sie können nicht wie hier ein Array von Zeichen einem anderen Array von Zeichen zuweisen. Sie müssen verwenden strcpy() oder eine Art Schleife, um jedes Element des Arrays zuzuweisen.

Benutzeravatar von Orion Edwards
Orion Edwards

Um Sparrs Antwort zu erweitern

Initialisierung und Zuweisung sind zwei unterschiedliche Operationen, die hier denselben Operator (“=”) verwenden.

Stellen Sie sich das so vor:

Stellen Sie sich vor, dass es 2 Funktionen gibt, die aufgerufen werden InitializeObjectund AssignObject. Wenn der Compiler sieht thing = valuees sieht sich den Kontext an und ruft eins auf InitializeObject wenn du neu machst thing. Wenn nicht, ruft es stattdessen an AssignObject.

Normalerweise ist das in Ordnung, da InitializeObject und AssignObject verhalten sich meist gleich. Außer beim Umgang mit Zeichen-Arrays (und einigen anderen Grenzfällen), in denen sie sich anders verhalten. Warum tun Sie das? Nun, das ist ein ganz anderer Beitrag, bei dem es um den Stapel gegen den Haufen und so weiter und so weiter geht.

PS: Abgesehen davon wird Ihnen diese Betrachtungsweise auch helfen, Kopierkonstrukteure und andere ähnliche Dinge zu verstehen, wenn Sie sich jemals in C++ wagen

Benutzeravatar von aib
aib

Beachten Sie, dass Sie immer noch Folgendes tun können:

s[0] = 'h';
s[1] = 'e';
s[2] = 'l';
s[3] = 'l';
s[4] = 'o';
s[5] = '\0';

Ich weiß, dass dies bereits beantwortet wurde, aber ich wollte eine Antwort teilen, die ich jemandem gegeben habe, der eine sehr ähnliche Frage in einer C/C++-Facebook-Gruppe gestellt hat.


Arrays haben keine Zuweisungsoperatorfunktionen*. Das bedeutet, dass Sie einem String-Literal nicht einfach ein char-Array zuweisen können. Wieso den? Weil das Array selbst keinen Zuweisungsoperator hat. (* Es ist ein konstanter Zeiger, der nicht geändert werden kann.)

Arrays sind einfach ein Bereich zusammenhängenden zugewiesenen Speichers, und der Name des Arrays ist eigentlich ein Zeiger auf das erste Element des Arrays. (Zitat aus https://www.quora.com/Can-we-copy-an-array-using-an-assignment-operator)

Um ein Zeichenfolgenliteral (wie z "Hello world" oder "abcd") in Ihr char-Array müssen Sie alle char-Elemente des Zeichenfolgenliterals manuell in das Array kopieren.

char s[100]; Dadurch wird ein leeres Array der Länge 100 initialisiert.

Um nun Ihr String-Literal in dieses Array zu kopieren, verwenden Sie strcpy

strcpy(s, "abcd"); Dadurch wird der Inhalt aus dem Zeichenfolgenliteral kopiert "abcd" und kopiere es in die s[100] Reihe.

Hier ist ein großartiges Beispiel dafür, was es tut:

int i = 0; //start at 0
do {
    s[i] = ("Hello World")[i]; //assign s[i] to the string literal index i
} while(s[i++]); //continue the loop until the last char is null

Sie sollten offensichtlich verwenden strcpy anstelle dieses benutzerdefinierten String-Literal-Kopierers, aber es ist ein gutes Beispiel, das erklärt, wie strcpy grundsätzlich funktioniert.

Hoffe das hilft!

1419630cookie-checkZuweisen von Zeichenketten zu Arrays von Zeichen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy