2010-02-24 8 views
14
#include <iostream> 


int main() 
{ 
    const std::string exclam = "!"; 
    const std::string message = "Hello" + ", world" + exclam; 
    std::cout << message; 
    return 0; 
} 

Warum funktioniert dieser Code nicht? Fehler zurückgegeben:Kann keine Zeichenfolgen in C++ hinzufügen

error: invalid operands of types `const char[6]' and `const char[8]' to binary `operator+' 

Vielen Dank im Voraus!

EDIT:

Danke für alle Antworten. Dies ist mein erstes Mal auf der Website und ich bin erstaunt über die Anzahl der ausführlichen Erklärungen in so kurzer Zeit.

In Bezug auf die eigentliche Frage. Wie kommt das funktioniert dann: ‚!‘

const std::string hello = "Hello"; 
const std::string message = hello + ", world" + "!"; 

Ist es, weil „Welt“ und danach mit der Variablen Hallo (die definiert ist) verkettet werden?

+0

Warum nicht tun: const std :: string message = "Hallo, Welt" + exclam; –

+0

Willkommen auf der Website! Nur zum Glück, wenn es eine Antwort gibt, die Sie mögen, stellen Sie sicher, dass Sie es akzeptieren. Sie werden wahrscheinlich in Zukunft Hilfe bekommen. – JasCav

Antwort

18

Da in C++, Stringliterale (wie "Hello" sind nicht vom Typ std::string. Sie sind schlicht char-Arrays oder C-Strings.

Also für die Linie const std::string message = "Hello" + ", world" + exclam;, die Typen der Compiler, mit zu arbeiten sind :

const std::string message = const char[6] + const char[8] + std::string;

und die Assoziativität von + gegeben, muss es die Operationen durchführen, sind:

const std::string message = ((const char[6] + const char[8]) + std::string);

Das heißt, die äußerste linke Addition muss zuerst ausgewertet werden, und das Ergebnis wird an die äußerste rechte Addition übergeben.

Also versucht der Compiler const char[6] + const char[8] auszuwerten. Für Arrays ist kein Zusatz definiert. Arrays werden implizit in Zeiger umgewandelt, was dem Compiler jedoch nicht hilft. Das bedeutet nur, dass es mit const char* + const char* endet, und für Zeiger wird kein Zusatz definiert.

An dieser Stelle weiß es nicht, dass das Ergebnis in eine std::string konvertiert werden soll.

jedoch in Ihrem zweiten Beispiel:

const std::string hello = "Hello"; 
const std::string message = hello + ", world" + "!"; 

es funktioniert, weil die Operationen der Compiler sehen würde, waren std::string + const char[8] + const char[2]. Hier kann die erste Addition in std::string + const char* umgewandelt werden, und hier ist der Additionsoperator definiert und gibt eine std::string zurück. So hat der Compiler die erste Addition erfolgreich herausgefunden, und da das Ergebnis eine Zeichenfolge war, sieht die zweite Addition wie folgt aus: std::string + const char[2], und wie zuvor ist dies nicht möglich, aber das Array kann in einen Zeiger und dann konvertiert werden Der Compiler ist in der Lage, einen Additionsoperator zu finden, der funktioniert, was wiederum zu einem std::string führt.

+5

+1, @jalf - ausgezeichnete Antwort –

4

In der Zeile, in der Sie Ihre Nachricht erstellen, wird zuerst der gesamte Ausdruck rechts neben dem = ausgeführt, und erst dann wird ihm eine C++ - Zeichenfolge zugewiesen. Zu diesem Zeitpunkt sind Ihr "Hallo" und Ihr ", Welt" immer noch C-Zeichenfolgen (const char []), weshalb Sie einen Fehler erhalten. Der Zusatz geht von links nach rechts, also wird das Paar der C-Strings hinzugefügt, bevor Sie versuchen, die Kombination zum std :: string exclam hinzuzufügen.

Sie müssen sie entweder innerhalb des Ausdrucks (z. B. std :: string ("Hello")) umsetzen oder String-Variablen für jeden erstellen, wie Sie es mit Exclam getan haben.

15
"Hello" + ", world" 

Da dies C-Style-Strings sind, können Sie sie nicht mit + anhängen. Sie können eine std :: string an eine c-style-Zeichenkette, aber nicht an 2 c-style-Zeichenketten anhängen, stattdessen fügen Sie einen std :: string() -Konstruktor um eine von ihnen hinzu, um eine temporäre, dh:

+4

Er könnte auch einfach den '+' Operator zwischen '" Hello "' und '" world "' wie: 'const std :: string message =" Hallo "", world "+ exclam;' Dies ist auch eine akzeptable Möglichkeit, String-Literale zu verketten. – fogo

4

String-Literale sind einfach null abgeschlossene Array von Zeichen in C++. Es gibt keinen Operator, mit dem Sie 2 Arrays von Zeichen in C++ hinzufügen können.

Es gibt jedoch ein char-Array und std :: string + -Operator.

ändern zu:

const std::string message = std::string("Hello") +", world" + exclam; 

In einigen Sprachen wie Python Stringliterale sind äquivalent zu Variablen des Typs Strings. C++ ist keine solche Sprache.

6

C++ macht nicht viele der automatischen Gespräche hinter den Kulissen anderer OO-Sprachen.

Wie Doug sagte, müssen Sie std :: string ("Hallo") + std :: string ("Welt") tun, die Sprache tut das nicht für Sie.

Sie können jedoch

std::cout << "hello" << "world" << exclam; 

tun Weil std :: cout weiß, wie ein const char drucken [] sowie einen String

3

C-Strings ("Hallo" und“Welt ") entsprechen anonymen Arrays:

static const char anon1[6] = { 'H', 'e', 'l', 'l', 'o', '\0' }; 
static const char anon2[8] = { ',', ' ', 'w', 'o', 'r', 'l', 'd', '\0' }; 

...Wenn Sie also "Hello" + ", world" eingeben, versuchen Sie, zwei Arrays anon1 + anon2 hinzuzufügen, die keine von C oder C++ unterstützte Operation sind.

Denken Sie daran, String-Literale in C/C++ sind nur Arrays (oder Adressen von Arrays). Sie müssen eine String-Klasse verwenden (z. B. std:string), um Operatoren wie + zu verwenden.

Verwandte Themen