@MatthieuM. Ihr Beispiel ist verwirrend. Ich denke, dass der Kern der Frage darin besteht, die ursprüngliche Zeichenfolge zu ändern. In Ihrem Beispiel ändern Sie die ursprüngliche Zeichenfolge nicht, da in Ihrem Beispiel die ursprüngliche Zeichenfolge "myString" heißt, was zu Verwirrung führt. in der frage ist es "st". Ihr Code sollte sein : st = st.substr(0, st.size()-1). Aber es sieht immer noch nicht richtig aus. Ich denke, dass der richtige Weg darin besteht, die für diese Aufgabe vorgesehene Funktion zu verwenden. Sie heißt erase () und der Code lautet : st.erase(st.size()-1). Dies würde als "mutierende Version" bezeichnet.
Czarek Tomczak
1
@CzarekTomczak: Ich verstehe, dass dies nicht genau das ist, wonach gefragt wurde, daher der Haftungsausschluss vor dem eigentlichen Kern.
Matthieu M.
2
@MattPhillips: Seine Lösung ist jedoch C ++ 11-spezifisch ( pop_backgab es in C ++ 03 nicht) und es handelt sich auch um eine direkte Modifikation (und das OP hat nie geklärt, ob er an Ort und Stelle wollte oder nicht) ... as so hat er eine richtige Antwort, aber nicht die einzig mögliche.
Matthieu M.
403
Einfache Lösung, wenn Sie C ++ 11 verwenden. Wahrscheinlich auch O (1) Zeit:
Als FYI - es wird nur von GCC 4.7 unterstützt (natürlich nicht mit dem Kompilierungsschalter -std = c ++ 11)
Shmil The Cat
20
Vergiss nicht zu überprüfen length().
Ja, es erscheint zu weit unten auf der Seite ..!
James Bedford
1
The behavior is undefined if the string is empty. von hier
Raffi
24
if(str.size ()>0) str.resize (str.size ()-1);
Eine std :: erase-Alternative ist gut, aber ich mag die "- 1" (ob basierend auf einer Größe oder einem Enditerator) - für mich hilft sie, die Absicht auszudrücken.
Übrigens - Gibt es wirklich kein std :: string :: pop_back? - erscheint merkwürdig.
Es gibt keine std::string::pop_backin C ++ 03; Es wurde jedoch in C ++ 0x hinzugefügt.
James McNellis
OK danke. Es hat ein bisschen Verwirrung gestiftet - ich könnte schwören, dass ich es benutzt habe, aber es ist nicht da. Vielleicht habe ich irgendwo eine nicht standardmäßige Bibliothek in einem Compiler (zwischen VC ++ 2003, VC ++ 2008, MinGW GCC3, MinGW GCC 4 und Linux GCC 4 gibt es einige Unterschiede). Wahrscheinlicher ist, dass ich nur mit anderen Typen verwechselt werde.
Steve314
resize () ist wahrscheinlich nicht für eine solche Verwendung vorgesehen, es ist eine speicherbezogene Funktion, erase () dient zum Löschen von Zeichen.
Czarek Tomczak
3
@Czarek Tomczak - Entschuldigung für die absurd späte Antwort, aber es resizeist eine Größenänderungsfunktion und keine Speicherfunktion mehr als alles andere, was den benötigten Speicher erhöhen könnte. Wenn Sie beispielsweise resizeeine kleinere Größe wählen, wird der reservierte Speicher nicht reduziert. Ich denke, Sie denken darüber nach reserve, was zumindest den zugewiesenen Speicher reduzieren könnte , wenn Sie dazu aufgefordert werden - siehe Größe hier ändern und hier reservieren .
Steve314
3
if (! str.empty ()) wird der Größe vorgezogen
ericcurtin
18
buf.erase(buf.size()-1);
Dies setzt voraus, dass Sie wissen, dass die Zeichenfolge nicht leer ist. In diesem Fall erhalten Sie eine out_of_rangeAusnahme.
buf [buf.size () - 1] = '\ 0'; entfernt nichts - es ändert nur das Zeichen, das dort war, um den Wert Null zu haben. std :; Strings können solche Zeichen gerne enthalten.
Neil ist richtig. Ich hätte das wahrscheinlich in meiner Antwort klarstellen sollen. Die zweite Option ändert effektiv den Wert des letzten Zeichens, damit es nicht gedruckt wird, aber die Zeichenfolgenlänge bleibt gleich. Durch Löschen wird das letzte Zeichen "entfernt" und die Größe der Zeichenfolge geändert.
RC.
@RC Es wird gedruckt, vorausgesetzt, Sie verwenden so etwas wie cout << buf. Wie es aussieht, hängt von Ihrer Plattform ab. Und Sie können dies jederzeit klarstellen, indem Sie Ihre Antwort bearbeiten.
Was ist viel besser über size() statt end()einer anderen Antwort?
Dies kann zu einer seltsamen Situation führen: Die Größe der Zeichenfolge wurde reduziert, aber das letzte Zeichen ist nicht auf '\ 0' gesetzt.
Deqing
1
@Deqing können Sie mehr Details darüber geben, was in einem solchen Fall passiert?
Ribamar
Zum Beispiel, wenn Sie haben string s("abc");, scheint es nach dem Löschen zu funktionieren: cout<<s; // prints "ab"Das letzte Zeichen ist jedoch noch da : cout<<s[2]; // still prints 'c'.
Deqing
1
leicht zu str[str.length()-1] = 0; str.erase(str.end()-1);
beheben
5
@Dequing: Ihr Beispiel ist ungültig. Durch das Löschen wird die Größe der Zeichenfolge verringert, sodass der Zugriff auf s[2]unzulässig ist.
CString str=CString("Hello world"); str.Delete(str.GetLength()-1);
Antworten:
Für eine nicht mutierende Version:
quelle
st = st.substr(0, st.size()-1)
. Aber es sieht immer noch nicht richtig aus. Ich denke, dass der richtige Weg darin besteht, die für diese Aufgabe vorgesehene Funktion zu verwenden. Sie heißt erase () und der Code lautet :st.erase(st.size()-1)
. Dies würde als "mutierende Version" bezeichnet.pop_back
gab es in C ++ 03 nicht) und es handelt sich auch um eine direkte Modifikation (und das OP hat nie geklärt, ob er an Ort und Stelle wollte oder nicht) ... as so hat er eine richtige Antwort, aber nicht die einzig mögliche.Einfache Lösung, wenn Sie C ++ 11 verwenden. Wahrscheinlich auch O (1) Zeit:
quelle
length()
.The behavior is undefined if the string is empty.
von hierEine std :: erase-Alternative ist gut, aber ich mag die "- 1" (ob basierend auf einer Größe oder einem Enditerator) - für mich hilft sie, die Absicht auszudrücken.
Übrigens - Gibt es wirklich kein std :: string :: pop_back? - erscheint merkwürdig.
quelle
std::string::pop_back
in C ++ 03; Es wurde jedoch in C ++ 0x hinzugefügt.resize
ist eine Größenänderungsfunktion und keine Speicherfunktion mehr als alles andere, was den benötigten Speicher erhöhen könnte. Wenn Sie beispielsweiseresize
eine kleinere Größe wählen, wird der reservierte Speicher nicht reduziert. Ich denke, Sie denken darüber nachreserve
, was zumindest den zugewiesenen Speicher reduzieren könnte , wenn Sie dazu aufgefordert werden - siehe Größe hier ändern und hier reservieren .Dies setzt voraus, dass Sie wissen, dass die Zeichenfolge nicht leer ist. In diesem Fall erhalten Sie eine
out_of_range
Ausnahme.quelle
size()
stattend()
einer anderen Antwort?str.erase( str.end()-1 )
Referenz: std :: string :: erase () Prototyp 2
Kein c ++ 11 oder c ++ 0x erforderlich.
quelle
string s("abc");
, scheint es nach dem Löschen zu funktionieren:cout<<s; // prints "ab"
Das letzte Zeichen ist jedoch noch da :cout<<s[2]; // still prints 'c'
.str[str.length()-1] = 0; str.erase(str.end()-1);
s[2]
unzulässig ist.Das ist alles was Sie brauchen:
quelle
quelle
Mit C ++ 11 benötigen Sie nicht einmal die Länge / Größe. Solange die Zeichenfolge nicht leer ist, können Sie Folgendes tun:
quelle
str.erase(str.begin() + str.size() - 1)
str.erase(str.rbegin())
kompiliert leider nicht dareverse_iterator
nicht in einen normal_iterator konvertiert werden kann.C ++ 11 ist in diesem Fall dein Freund.
quelle
str.erase(str.end() - 1)
?Wenn die Länge nicht Null ist, können Sie auch
quelle
\0
ändert sich die Länge der Zeichenfolge nicht.str.length()
wird ungenau sein.