Wie füge ich ein Zeichen an einen std :: string an?

175

Folgendes schlägt mit dem Fehler fehl prog.cpp:5:13: error: invalid conversion from ‘char’ to ‘const char*’

int main()
{
  char d = 'd';
  std::string y("Hello worl");
  y.append(d); // Line 5 - this fails
  std::cout << y;
  return 0;
}

Ich habe auch Folgendes versucht, das kompiliert, sich aber zur Laufzeit zufällig verhält:

int main()
{
  char d[1] = { 'd' };
  std::string y("Hello worl");
  y.append(d);
  std::cout << y;
  return 0;
}

Entschuldigung für diese dumme Frage, aber ich habe mich bei Google umgesehen. Was ich sehen konnte, sind nur "char array to char ptr", "char ptr to char array" usw.

ertrinken
quelle
ein Compilerfehler ja..Ich habe vergessen, was der Fehler ist, aber es ist vernünftig.
Ertrinken
3
Sie haben unten bessere Antworten, aber Sie können Ihr zweites Beispiel dazu bringen, wie folgt zu arbeiten. Char d [2] = {'d', 0}; oder einfach char d [2] = "d"; Grundsätzlich benötigen Sie eine 0, um Ihre Zeichenfolge im C-Stil zu beenden, die Sie anhängen
sbk
Gute Dokumentation hier: sgi.com/tech/stl/basic_string.html
Martin York

Antworten:

224
y += d;

Ich würde +=Operator anstelle von benannten Funktionen verwenden.

AraK
quelle
2
Warum halten Sie + = für besser als push_back? Ist es nur weniger tippen oder haben Sie einen anderen Grund?
Glen
4
Es ist weniger tippen. In gcc, basic_string::operator+=ist nur ein Anruf in push_back.
Eduffy
2
Es ist natürlicher IMO für Saiten. push_back ist eine Containerfunktion und eine Zeichenfolge ist eine spezialisierte in STL :)
AraK
6
Lassen Sie uns diese Frage umdrehen: Warum halten Sie push_back für besser als + =? Meiner Meinung nach ist + = klar und prägnant.
Jesper
34
Sie möchten damit vorsichtig sein, denn wenn Sie sich daran gewöhnen, wird dies gut kompiliert, wenn yes ein char*statt ist std::string. Es würde ddem Zeiger y Zeichen hinzufügen .
Zan Lynx
65

Verwendung push_back():

std::string y("Hello worl");
y.push_back('d')
std::cout << y;
Ferdinand Beyer
quelle
19

Um einem std :: string var mit der append-Methode ein Zeichen hinzuzufügen, müssen Sie diese Überladung verwenden:

std::string::append(size_type _Count, char _Ch)

Bearbeiten: Sie haben Recht, ich habe den Parameter size_type, der in der Kontexthilfe angezeigt wird, falsch verstanden. Dies ist die Anzahl der hinzuzufügenden Zeichen. Der richtige Anruf ist also

s.append(1, d);

nicht

s.append(sizeof(char), d);

Oder der einfachste Weg:

s += d;
Patrice Bernassola
quelle
Ich denke, die Verwendung von sizeof ist hier nicht semantisch korrekt (obwohl es zufällig funktioniert, da sizeof (char) immer eins ist). Die Append-Methode ist natürlich nützlicher, wenn Sie mehr Kopien desselben Zeichens anhängen möchten !!!!!!!!!!
UncleBens
1
Warum benutzt du sizeof(char)statt 1? Sie möchten genau eine Wiederholung von anhängen d, also sagen Sie das einfach. Die Verwendung sizeofhier ist irreführend, da dies darauf hindeutet, dass appenddie Bytegröße des verwendeten Datentyps angegeben werden muss (was nicht der Fall ist).
Ferdinand Beyer
Wie Unclebens sagte, ist die Append-Methode wirklich nützlicher, wenn dasselbe Zeichen mehrmals hinzugefügt wird.
Patrice Bernassola
10

Zusätzlich zu den anderen erwähnten nimmt einer der String-Konstruktoren ein Zeichen und die Anzahl der Wiederholungen für dieses Zeichen. Damit können Sie ein einzelnes Zeichen anhängen.

std::string s = "hell";
s += std::string(1, 'o');
Brian R. Bondy
quelle
7

Ich teste die verschiedenen Sätze, indem ich sie in eine große Schleife laufe. Ich habe Microsoft Visual Studio 2015 als Compiler verwendet und mein Prozessor ist ein i7, 8Hz, 2GHz.

    long start = clock();
    int a = 0;
    //100000000
    std::string ret;
    for (int i = 0; i < 60000000; i++)
    {
        ret.append(1, ' ');
        //ret += ' ';
        //ret.push_back(' ');
        //ret.insert(ret.end(), 1, ' ');
        //ret.resize(ret.size() + 1, ' ');
    }
    long stop = clock();
    long test = stop - start;
    return 0;

Nach diesem Test sind die Ergebnisse:

     operation             time(ms)            note
------------------------------------------------------------------------
append                     66015
+=                         67328      1.02 time slower than 'append'
resize                     83867      1.27 time slower than 'append'
push_back & insert         90000      more than 1.36 time slower than 'append'

Fazit

+= scheint verständlicher, aber wenn Sie sich für Geschwindigkeit interessieren, verwenden Sie Anhängen

Hugo Zevetel
quelle
Damit eine solche Antwort aussagekräftig ist, sollten Sie zumindest angeben, welchen Compiler Sie verwenden, da solche Dinge sehr unterschiedlich sein können. Es kann auch großartig sein, über Ihren Prozessor zu erzählen, um eine grobe Schätzung der tatsächlichen Auswirkungen zu erhalten, die dies haben könnte.
Akaltar
Ich habe Visual Studio 2015 verwendet. Ich werde nach gcc suchen, um einige andere Tests durchzuführen. Mein Prozessor ist i7, 8 Herzen, 2,20 GHz .... Aber was auch immer mein Prozessor ist, es wird keinen Einfluss auf die Implementierung von std :: string haben ... es sei denn, einige dieser Methoden sind Multithread-Methoden und andere nicht.
Hugo Zevetel
Manchmal hat dies Auswirkungen, insbesondere wenn Sie Timings in Millisekunden anzeigen. Stattdessen können Sie in Prozent relativ zur schnellsten Methode anzeigen (die tatsächliche Prozessorgeschwindigkeit spielt also keine Rolle). Verschieben Sie diese Daten auch aus dem Kommentar in Ihre Antwort. Dies ist nur eine allgemeine StackExchange-Etikette. Ansonsten schöne Antwort.
Akaltar
6

Versuchen , den Operator + = Link - Text , append () Methode Link - Text oder push_back () Methode Link - Text

Die Links in diesem Beitrag enthalten auch Beispiele für die Verwendung der jeweiligen APIs.

Michael Berg
quelle
2

das Problem mit:

std::string y("Hello worl");
y.push_back('d')
std::cout << y;

ist, dass Sie das 'd' haben müssen, anstatt einen Namen eines Zeichens zu verwenden, wie char d = 'd'; Oder liege ich falsch?

Alex Spencer
quelle
Ich habe es gerade versucht und es hat gut funktioniert. Ich habe char c = 'd'und ich kann y.push_back(c)ohne Probleme auskommen. Es gibt also kein Problem mit std::string::push_back()(außer dass es länger ist als +=).
Franklin Yu
1
int main()
{
  char d = 'd';
  std::string y("Hello worl");

  y += d;
  y.push_back(d);
  y.append(1, d); //appending the character 1 time
  y.insert(y.end(), 1, d); //appending the character 1 time
  y.resize(y.size()+1, d); //appending the character 1 time
  y += std::string(1, d); //appending the character 1 time
}

Beachten Sie, dass Sie in all diesen Beispielen ein Zeichenliteral direkt hätten verwenden können : y += 'd';.

Ihr zweites Beispiel hätte aus nicht verwandten Gründen fast funktioniert. char d[1] = { 'd'};hat nicht funktioniert, aber char d[2] = { 'd'};(beachten Sie, dass das Array die Größe zwei hat) hätte ungefähr genauso funktioniert wie const char* d = "d";, und ein String-Literal kann angehängt werden : y.append(d);.

Mooing Duck
quelle
1

Versuchen Sie, das d als Zeiger y.append (* d) zu verwenden.

2.less
quelle
Das ist gefährlich, da eine Single charkeine Zeichenfolge ist und keinen Nullterminator hat. Dies führt zu undefiniertem Verhalten.
Simon Kraemer
Das ist einfach falsch. *dbedeutet Referenzreferenzzeiger, dder ein Syntaxfehler ist, da er dkein Zeiger ist.
Franklin Yu
0
str.append(10u,'d'); //appends character d 10 times

Beachten Sie, dass ich 10u und nicht 10 geschrieben habe, wie oft ich das Zeichen anhängen möchte. Ersetzen Sie 10 durch eine beliebige Zahl.

Ioan Stef
quelle
0

Ich habe einen einfachen Weg gefunden ... Ich musste chareine Schnur anheften , die im laufenden Betrieb gebaut wurde. Ich brauchte eine, char list;weil ich dem Benutzer eine Auswahl gab und diese Auswahl in einer switch()Anweisung verwendete.

Ich habe einfach eine weitere hinzugefügt std::string Slist;und die neue Zeichenfolge gleich dem Zeichen "Liste" gesetzt - a, b, c oder was auch immer der Endbenutzer so auswählt:

char list;
std::string cmd, state[], Slist;
Slist = list; //set this string to the chosen char;
cmd = Slist + state[x] + "whatever";
system(cmd.c_str());

Komplexität mag cool sein, aber Einfachheit ist cooler. meiner bescheidenen Meinung nach

Charles H.
quelle
0

Hinzufügen einer Einfügeoption, wie noch nicht erwähnt.

std::string str("Hello World");
char ch;

str.push_back(ch);  //ch is the character to be added
OR
str.append(sizeof(ch),ch);
OR
str.insert(str.length(),sizeof(ch),ch) //not mentioned above
Gopesh Bharadwaj
quelle
-1

Wenn Sie push_back verwenden, wird der String-Konstruktor nicht aufgerufen. Andernfalls wird durch Casting ein Zeichenfolgenobjekt erstellt und das Zeichen in dieser Zeichenfolge zur anderen Zeichenfolge hinzugefügt. Zu viel Ärger für einen winzigen Charakter;)

Progiker
quelle
1
Operator + = (char c); ist für Strings überladen. Tatsächlich akzeptiert der String-Konstruktor kein Zeichen, siehe Antwort von Brian;)
AraK