C # verfügt über eine Syntaxfunktion, mit der Sie viele Datentypen in einer Zeile zusammenfassen können.
string s = new String();
s += "Hello world, " + myInt + niceToSeeYouString;
s += someChar1 + interestingDecimal + someChar2;
Was wäre das Äquivalent in C ++? Soweit ich sehen kann, müssten Sie alles in separaten Zeilen ausführen, da mit dem Operator + nicht mehrere Zeichenfolgen / Variablen unterstützt werden. Das ist in Ordnung, sieht aber nicht so ordentlich aus.
string s;
s += "Hello world, " + "nice to see you, " + "or not.";
Der obige Code erzeugt einen Fehler.
c++
string
compiler-errors
concatenation
Nick Bolton
quelle
quelle
char *
, einander Zeiger hinzuzufügen . Das ist es, was den Fehler erzeugt - weil das Summieren von Zeigern unsinnig ist. Machen Sie, wie unten erwähnt, mindestens den 1. Operanden zu einemstd::string
, und es gibt überhaupt keinen Fehler.Antworten:
Schauen Sie sich diesen Guru Of The Week-Artikel von Herb Sutter an: The String Formatters of Manor Farm
quelle
std::string s = static_cast<std::ostringstream&>(std::ostringstream().seekp(0) << "HelloWorld" << myInt << niceToSeeYouString).str();
std::stringstream ss; ss << "Hello, world, " << myInt << niceToSeeYouString; std::string s = ss.str();
ist so ziemlich einzeiligIn 5 Jahren hat niemand erwähnt
.append
?quelle
s.append("One"); s.append(" line");
s.append("One").append(" expression");
Vielleicht sollte ich das Original bearbeiten, um den Rückgabewert auf diese Weise zu verwenden?s
im entsprechenden C # -Code und in seinem nicht kompilierten C ++ - Code in einer anderen Zeile. Sein gewünschtes C ++ ists += "Hello world, " + "nice to see you, " + "or not.";
das, was geschrieben werden kanns.append("Hello world, ").append("nice to see you, ").append("or not.");
append
ist, dass es auch funktioniert, wenn die Zeichenfolgen NUL-Zeichen enthalten.Diese Zeichenarray-Literale sind keine C ++ std :: Strings - Sie müssen sie konvertieren:
Um Ints (oder einen anderen streambaren Typ) zu konvertieren, können Sie einen Boost lexical_cast verwenden oder Ihre eigene Funktion bereitstellen:
Sie können jetzt Dinge sagen wie:
quelle
string("Hello world")
werden überoperator+()
in der Klasse definiert ausgeführtstring
. Wennstring
der Ausdruck kein Objekt enthält, wird die Verkettung zu einer bloßen Summe von Zeichenzeigernchar*
.Ihr Code geschrieben werden kann als 1 ,
... aber ich bezweifle, dass Sie danach suchen. In Ihrem Fall suchen Sie wahrscheinlich nach Streams:
1 " kann geschrieben werden als ": Dies funktioniert nur für String-Literale. Die Verkettung erfolgt durch den Compiler.
quelle
const char smthg[] = "smthg"
: / Ist es ein Fehler?#define
deine Saite umgehen, obwohl dies seine eigenen Probleme mit sich bringt.Die Verwendung von benutzerdefinierten C ++ 14-Literalen und
std::to_string
dem Code wird einfacher.Beachten Sie, dass die Verkettung von Zeichenfolgenliteralen zur Kompilierungszeit erfolgen kann. Entfernen Sie einfach die
+
.quelle
std::literals::string_literals
, nicht auf das Konzept einer UDL.Um eine Lösung anzubieten, die mehr einzeilig ist: Eine Funktion
concat
kann implementiert werden, um die "klassische" Stringstream-basierte Lösung auf eine einzige Anweisung zu reduzieren . Es basiert auf verschiedenen Vorlagen und perfekter Weiterleitung.Verwendung:
Implementierung:
quelle
In C ++ 20 können Sie Folgendes tun:
Bis dahin können Sie dasselbe mit der {fmt} -Bibliothek tun :
Haftungsausschluss : Ich bin der Autor von {fmt}.
quelle
boost :: format
oder std :: stringstream
quelle
Das eigentliche Problem war, dass das Verketten von String-Literalen mit
+
in C ++ fehlschlägt:In C ++ (auch in C) verketten Sie Zeichenfolgenliterale, indem Sie sie direkt nebeneinander platzieren:
Dies ist sinnvoll, wenn Sie Code in Makros generieren:
... ein einfaches Makro, das so verwendet werden kann
( Live-Demo ... )
oder, wenn Sie darauf bestehen, die
+
for-String-Literale zu verwenden (wie bereits von underscore_d vorgeschlagen ):Eine andere Lösung kombiniert eine Zeichenfolge und eine
const char*
für jeden Verkettungsschrittquelle
sprintf
eine Option, aber es gibt auch std :: stringstream , das Probleme mit untergroßen Puffern verhindert.quelle
Sie müssten den Operator + () für jeden Datentyp definieren, den Sie mit der Zeichenfolge verknüpfen möchten. Da jedoch der Operator << für die meisten Typen definiert ist, sollten Sie std :: stringstream verwenden.
Verdammt, um 50 Sekunden geschlagen ...
quelle
std::string operator+(std::string s, int i){ return s+std::to_string(i); }
Wenn Sie das ausschreiben
+=
, sieht es fast genauso aus wie C #quelle
Wie andere sagten, besteht das Hauptproblem mit dem OP-Code darin, dass der Bediener
+
nicht verkettetconst char *
; es funktioniert jedoch mitstd::string
.Hier ist eine weitere Lösung, die C ++ 11-Lambdas verwendet
for_each
und dieseparator
Trennung von Zeichenfolgen ermöglicht:Verwendung:
Es scheint gut (linear) zu skalieren, zumindest nach einem kurzen Test auf meinem Computer; Hier ist ein kurzer Test, den ich geschrieben habe:
Ergebnisse (Millisekunden):
quelle
Vielleicht gefällt Ihnen meine "Streamer" -Lösung, um es wirklich in einer Zeile zu tun:
quelle
Hier ist die Einzeiler-Lösung:
Obwohl es ein bisschen hässlich ist, denke ich, dass es ungefähr so sauber ist, wie Sie es in C ++ bekommen.
Wir werfen das erste Argument auf a
std::string
und verwenden dann die (von links nach rechts) Bewertungsreihenfolge von,operator+
um sicherzustellen, dass der linke Operand immer a iststd::string
. Auf diese Weise verketten wirstd::string
das links mit demconst char *
Operanden rechts und geben einen anderen zurückstd::string
, wodurch der Effekt kaskadiert wird.Hinweis: es gibt ein paar Optionen für den rechten Operanden, einschließlich
const char *
,std::string
undchar
.Es liegt an Ihnen zu entscheiden, ob die magische Zahl 13 oder 6227020800 ist.
quelle
Sie können diesen Header in diesem Zusammenhang verwenden: https://github.com/theypsilon/concat
Unter der Haube verwenden Sie einen std :: ostringstream.
quelle
Wenn Sie bereit sind, können
c++11
Sie benutzerdefinierte Zeichenfolgenliterale verwenden und zwei Funktionsvorlagen definieren, die den Plus-Operator für einstd::string
Objekt und jedes andere Objekt überladen . Die einzige Gefahr besteht darin, die Plus-Operatoren von nicht zu überladenstd::string
, da der Compiler sonst nicht weiß, welchen Operator er verwenden soll. Sie können dies tun, indem Sie die Vorlagestd::enable_if
von verwendentype_traits
. Danach verhalten sich Strings wie in Java oder C #. Einzelheiten finden Sie in meiner Beispielimplementierung.Haupt code
Datei c_sharp_strings.hpp
Fügen Sie diese Header-Datei an allen Stellen ein, an denen Sie diese Zeichenfolgen haben möchten.
quelle
So etwas funktioniert bei mir
quelle
Basierend auf den oben genannten Lösungen habe ich eine Klasse var_string für mein Projekt erstellt, um das Leben einfacher zu machen. Beispiele:
Die Klasse selbst:
Sie fragen sich immer noch, ob es in C ++ etwas Besseres geben wird?
quelle
In c11:
Auf diese Weise können Sie einen Funktionsaufruf wie folgt erstellen:
wird gedruckt: Nachrichtennummer: 10
quelle
Sie können auch die Zeichenfolgenklasse "erweitern" und den gewünschten Operator auswählen (<<, &, |, etc ...).
Hier ist der Code, der den Operator << verwendet, um anzuzeigen, dass kein Konflikt mit Streams besteht
Hinweis: Wenn Sie s1.reserve (30) auskommentieren, gibt es nur 3 neue () Operatoranforderungen (1 für s1, 1 für s2, 1 für Reserve; Sie können leider nicht zur Konstruktorzeit reservieren). Ohne Vorbehalt muss s1 mehr Speicher anfordern, wenn er wächst. Dies hängt also vom Wachstumsfaktor Ihrer Compiler-Implementierung ab (meiner scheint in diesem Beispiel 1,5, 5 neue () Aufrufe zu sein.)
quelle
Stringstream mit einem einfachen Präprozessor-Makro, das eine Lambda-Funktion verwendet, scheint nett zu sein:
und dann
quelle
Das funktioniert bei mir:
Ausgabe:
quelle
const
oder (wenn kein Speicher erforderlich ist) einenum
?Haben Sie versucht, das + = zu vermeiden? Verwenden Sie stattdessen var = var + ... es hat bei mir funktioniert.
quelle
#include <iostream.h> // string
#include <system.hpp> // ansiString