Jak mogę usunąć ostatni znak z ciągu C ++?
Próbowałem st = substr(st.length()-1);
Ale to nie zadziałało.
CString str=CString("Hello world"); str.Delete(str.GetLength()-1);
Jak mogę usunąć ostatni znak z ciągu C ++?
Próbowałem st = substr(st.length()-1);
Ale to nie zadziałało.
CString str=CString("Hello world"); str.Delete(str.GetLength()-1);
Odpowiedzi:
W przypadku wersji niemutującej:
st = myString.substr(0, myString.size()-1);
st = st.substr(0, st.size()-1)
. Ale to nadal nie wygląda we właściwy sposób, myślę, że właściwym sposobem jest użycie funkcji, który jest przeznaczony do tego zadania, to się nazywa erase (), a kod jest: st.erase(st.size()-1)
. Nazywa się to „wersją mutującą”.
pop_back
nie istniało w C ++ 03) i jest to również modyfikacja na miejscu (a OP nigdy nie wyjaśnił, czy chce na miejscu, czy nie) ... as takie, że ma się poprawną odpowiedź, ale nie jest to możliwe tylko jeden.
Proste rozwiązanie, jeśli używasz C ++ 11. Prawdopodobnie również czas O (1):
st.pop_back();
if (str.size () > 0) str.resize (str.size () - 1);
Alternatywa std :: erase jest dobra, ale podoba mi się „- 1” (niezależnie od tego, czy jest to rozmiar, czy iterator końcowy) - pomaga mi wyrazić zamiar.
BTW - Czy naprawdę nie ma std :: string :: pop_back? - wydaje się dziwny.
std::string::pop_back
w C ++ 03; został jednak dodany w C ++ 0x.
resize
jest to funkcja zmiany rozmiaru i nie jest już funkcją pamięci, niż cokolwiek innego, co mogłoby zwiększyć potrzebną pamięć. Na przykład, jeśli masz resize
mniejszy rozmiar, nie zmniejszy to zarezerwowanej pamięci. Myślę, że myślisz o tym reserve
, co najmniej może zmniejszyć przydzieloną pamięć, jeśli zostaniesz o to poproszony - zobacz tutaj zmień rozmiar i zarezerwuj tutaj .
buf.erase(buf.size() - 1);
Zakłada się, że wiesz, że ciąg nie jest pusty. Jeśli tak, otrzymasz out_of_range
wyjątek.
size()
w porównaniu end()
z inną odpowiedzią?
str.erase( str.end()-1 )
Odniesienie: prototyp std :: string :: erase () 2
nie wymaga c ++ 11 lub c ++ 0x.
string s("abc");
po erase wydaje robocza: cout<<s; // prints "ab"
jednak ostatni znak jest nadal istnieje: cout<<s[2]; // still prints 'c'
.
str[str.length()-1] = 0; str.erase(str.end()-1);
s[2]
jest nielegalny.
Dzięki C ++ 11 nie potrzebujesz nawet długości / rozmiaru. Dopóki łańcuch nie jest pusty, możesz wykonać następujące czynności:
if (!st.empty())
st.erase(std::prev(st.end())); // Erase element referred to by iterator one
// before the end
str.erase(str.begin() + str.size() - 1)
str.erase(str.rbegin())
nie kompiluje się niestety, ponieważ reverse_iterator
nie można go przekonwertować na normal_iterator.
C ++ 11 jest twoim przyjacielem w tym przypadku.
str.erase(str.end() - 1)
?
Jeśli długość nie jest równa zero, możesz również
str[str.length() - 1] = '\0';
\0
nie zmienia długości łańcucha. str.length()
będzie niedokładny.