@ MatthieuM. Contoh Anda membingungkan, saya pikir inti dari pertanyaan adalah untuk memodifikasi string asli, dalam contoh Anda Anda tidak mengubah string asli, karena dalam contoh Anda string asli disebut "myString" yang memberikan kebingungan, dalam pertanyaan itu adalah "st". Kode Anda harus: st = st.substr(0, st.size()-1). Tapi itu masih tidak terlihat dengan cara yang benar, saya berpikir bahwa cara yang tepat adalah dengan menggunakan fungsi yang dimaksudkan untuk tugas ini, itu disebut menghapus () dan kode ini: st.erase(st.size()-1). Ini akan disebut "versi mutasi".
Czarek Tomczak
1
@CzarekTomczak: Saya mengerti ini bukan apa yang diminta, jadi penafian sebelum inti sebenarnya.
Matthieu M.
2
@MattPhillips: solusinya adalah spesifik C ++ 11 ( pop_backtidak ada di C ++ 03) dan ini juga merupakan modifikasi di tempat (dan OP tidak pernah mengklarifikasi apakah ia ingin ada atau tidak) ... karena seperti, ia memiliki sebuah jawaban yang benar, tetapi bukan satu-satunya yang mungkin.
Matthieu M.
404
Solusi sederhana jika Anda menggunakan C ++ 11. Mungkin juga O (1) kali:
Tidak ada std::string::pop_backdalam C ++ 03; sudah ditambahkan di C ++ 0x.
James McNellis
Ok terima kasih. Ini menyebabkan sedikit kebingungan - saya bersumpah saya telah menggunakannya, tetapi itu tidak ada. Mungkin saya memiliki pustaka non-standar di beberapa kompiler di suatu tempat (antara VC ++ 2003, VC ++ 2008, MinGW GCC3, MinGW GCC 4 dan Linux GCC 4, Anda mendapatkan beberapa perbedaan). Lebih mungkin, saya hanya bingung dengan jenis lain.
Steve314
mengubah ukuran () mungkin tidak dimaksudkan untuk penggunaan seperti itu, ini adalah fungsi terkait memori, hapus () adalah untuk menghapus karakter.
Czarek Tomczak
3
@Czarek Tomczak - maaf atas keterlambatan keterlambatan jawaban, tetapi resizemerupakan fungsi mengubah ukuran, dan tidak ada lagi fungsi memori yang hal lain yang dapat meningkatkan memori yang dibutuhkan. Misalnya, jika Anda resizeke ukuran yang lebih kecil, itu tidak akan mengurangi memori yang dipesan. Saya pikir Anda sedang memikirkan reserve, yang setidaknya dapat mengurangi memori yang dialokasikan jika diminta untuk - lihat mengubah ukuran di sini dan memesan di sini .
Steve314
3
if (! str.empty ()) lebih disukai daripada ukuran
ericcurtin
19
buf.erase(buf.size()-1);
Ini mengasumsikan Anda tahu bahwa string tidak kosong. Jika demikian, Anda akan mendapatkan out_of_rangepengecualian.
buf [buf.size () - 1] = '\ 0'; tidak menghapus apa pun - itu hanya mengubah karakter yang ada di sana untuk memiliki nilai nol. std:; string dengan senang hati bisa mengandung karakter tersebut.
Neil benar. Saya mungkin harus menjelaskan ini dalam jawaban saya. Opsi kedua akan secara efektif mengubah nilai karakter terakhir sehingga tidak akan dicetak, tetapi panjang string tetap sama. Menggunakan hapus sebenarnya "menghilangkan" karakter terakhir dan akan mengubah ukuran string.
RC.
@RC Akan dicetak, dengan asumsi Anda menggunakan sesuatu seperti cout << buf. Bagaimana tampilannya akan tergantung pada platform Anda. Dan Anda selalu dapat mengklarifikasi dengan mengedit jawaban Anda.
Apa yang jauh lebih baik size() daripada end()jawaban lain?
Ini dapat menyebabkan situasi aneh: ukuran string telah berkurang tetapi karakter terakhir tidak disetel ke '\ 0'.
Deqing
1
@Deqing dapatkah Anda memberikan detail lebih lanjut tentang apa yang terjadi dalam kasus seperti itu?
ribamar
Sebagai contoh jika Anda telah string s("abc");, setelah menghapus tampaknya bekerja: cout<<s; // prints "ab"Namun, karakter terakhir masih ada: cout<<s[2]; // still prints 'c'.
Deqing
1
mudah diperbaiki: hanyastr[str.length()-1] = 0; str.erase(str.end()-1);
taxilian
5
@Dequing: contoh Anda tidak valid. Penghapusan mengurangi ukuran string, sehingga akses ke s[2]ilegal.
CString str=CString("Hello world"); str.Delete(str.GetLength()-1);
Jawaban:
Untuk versi yang tidak bermutasi:
sumber
st = st.substr(0, st.size()-1)
. Tapi itu masih tidak terlihat dengan cara yang benar, saya berpikir bahwa cara yang tepat adalah dengan menggunakan fungsi yang dimaksudkan untuk tugas ini, itu disebut menghapus () dan kode ini:st.erase(st.size()-1)
. Ini akan disebut "versi mutasi".pop_back
tidak ada di C ++ 03) dan ini juga merupakan modifikasi di tempat (dan OP tidak pernah mengklarifikasi apakah ia ingin ada atau tidak) ... karena seperti, ia memiliki sebuah jawaban yang benar, tetapi bukan satu-satunya yang mungkin.Solusi sederhana jika Anda menggunakan C ++ 11. Mungkin juga O (1) kali:
sumber
length()
.The behavior is undefined if the string is empty.
dari siniAlternatif std :: erase baik, tapi saya suka "- 1" (baik berdasarkan ukuran atau end-iterator) - bagi saya, ini membantu mengekspresikan maksud.
BTW - Apakah benar-benar tidak ada std :: string :: pop_back? - sepertinya aneh.
sumber
std::string::pop_back
dalam C ++ 03; sudah ditambahkan di C ++ 0x.resize
merupakan fungsi mengubah ukuran, dan tidak ada lagi fungsi memori yang hal lain yang dapat meningkatkan memori yang dibutuhkan. Misalnya, jika Andaresize
ke ukuran yang lebih kecil, itu tidak akan mengurangi memori yang dipesan. Saya pikir Anda sedang memikirkanreserve
, yang setidaknya dapat mengurangi memori yang dialokasikan jika diminta untuk - lihat mengubah ukuran di sini dan memesan di sini .Ini mengasumsikan Anda tahu bahwa string tidak kosong. Jika demikian, Anda akan mendapatkan
out_of_range
pengecualian.sumber
size()
daripadaend()
jawaban lain?str.erase( str.end()-1 )
Referensi: std :: string :: erase () prototipe 2
tidak diperlukan c ++ 11 atau c ++ 0x.
sumber
string s("abc");
, setelah menghapus tampaknya bekerja:cout<<s; // prints "ab"
Namun, karakter terakhir masih ada:cout<<s[2]; // still prints 'c'
.str[str.length()-1] = 0; str.erase(str.end()-1);
s[2]
ilegal.Itu yang Anda butuhkan:
sumber
sumber
Dengan C ++ 11, Anda bahkan tidak perlu panjang / ukuran. Selama string tidak kosong, Anda dapat melakukan hal berikut:
sumber
str.erase(str.begin() + str.size() - 1)
str.erase(str.rbegin())
sayangnya tidak mengkompilasi, karenareverse_iterator
tidak dapat dikonversi ke normal_iterator.C ++ 11 adalah teman Anda dalam hal ini.
sumber
str.erase(str.end() - 1)
?Jika panjangnya bukan nol, Anda juga bisa
sumber
\0
tidak mengubah panjang string.str.length()
akan tidak akurat.