Apa cara yang disukai untuk menghapus spasi dari string di C ++? Saya bisa mengulang semua karakter dan membuat string baru, tetapi apakah ada cara yang lebih baik?
222
Hal terbaik untuk dilakukan adalah menggunakan algoritme remove_if
dan ruang:
remove_if(str.begin(), str.end(), isspace);
Sekarang algoritma itu sendiri tidak dapat mengubah wadah (hanya memodifikasi nilai-nilai), jadi itu benar-benar mengocok nilai-nilai di sekitar dan mengembalikan pointer ke tempat akhir sekarang seharusnya. Jadi kita harus memanggil string :: erase untuk benar-benar memodifikasi panjang wadah:
str.erase(remove_if(str.begin(), str.end(), isspace), str.end());
Kami juga harus mencatat bahwa remove_if akan membuat paling banyak satu salinan data. Berikut ini contoh implementasi:
template<typename T, typename P>
T remove_if(T beg, T end, P pred)
{
T dest = beg;
for (T itr = beg;itr != end; ++itr)
if (!pred(*itr))
*(dest++) = *itr;
return dest;
}
erase
sesudahnya. Itu akan mengembalikan hasil yang benar.isspace
adalah UB untuk semua set karakter kecuali ASCII 7-bit asli. C99 §7.4 / 1. itu tidak mengejutkan saya bahwa itu sudah upvoted untuk lagu 71 orang sekarang, meskipun menjadi sangat buruk Saran.isspace
, untuk semua karakter non-ASCII, dengan pilihan standar praktik dalam penandatanganan untukchar
. Dengan demikian ia memiliki perilaku yang tidak jelas . Saya mengulanginya karena saya curiga ada upaya yang disengaja untuk menenggelamkan fakta itu dalam kebisingan.sumber
<algorithm>
ini agar berfungsi.Dari gamedev
sumber
::isspace
adalah UB.Bisakah Anda menggunakan Boost String Algo? http://www.boost.org/doc/libs/1_35_0/doc/html/string_algo/usage.html#id1290573
sumber
remove_if(str.begin(), str.end(), isspace);
yang disebutkan oleh Matt Price. Saya tidak tahu kenapa. Sebenarnya, semua hal yang meningkatkan, yang memiliki alternatif STL, lebih lambat daripada yang gcc yang sesuai (Semua yang saya diuji). Beberapa dari mereka jauh lebih lambat! (hingga 5 kali dalam sisipan unordered_map) Mungkin itu karena cache CPU dari lingkungan bersama atau sesuatu seperti itu.Untuk pemangkasan, gunakan algoritma peningkatan string :
sumber
Anda dapat menggunakan solusi ini untuk menghapus char:
sumber
Hai, Anda bisa melakukan hal seperti itu. Fungsi ini menghapus semua spasi.
Saya membuat fungsi lain, yang menghapus semua ruang yang tidak perlu.
sumber
Gunakan:
sumber
Jika Anda ingin melakukan ini dengan makro yang mudah, berikut ini:
Ini mengasumsikan Anda sudah melakukan
#include <string>
tentu saja.Sebut seperti ini:
sumber
Saya menggunakan pekerjaan di bawah ini untuk waktu yang lama - tidak yakin tentang kerumitannya.
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return (f==' '||s==' ');}),s.end());
ketika Anda ingin menghapus karakter
' '
dan beberapa misalnya-
digunakans.erase(std::unique(s.begin(),s.end(),[](char s,char f){return ((f==' '||s==' ')||(f=='-'||s=='-'));}),s.end());
juga hanya menambah
||
jika jumlah karakter yang ingin Anda hapus bukan 1tetapi seperti yang disebutkan oleh orang lain menghapus idiom hapus juga tampak baik-baik saja.
sumber
Kode ini pada dasarnya mengambil string dan beralih melalui setiap karakter di dalamnya. Itu kemudian memeriksa apakah string itu adalah spasi, jika tidak maka karakter ditambahkan ke string baru.
sumber
Sumber:
Referensi diambil dari forum ini .
sumber
Di C ++ 20 Anda dapat menggunakan fungsi std :: erase gratis
Contoh lengkap:
Saya mencetak | sehingga jelas bahwa ruang di awal juga dihilangkan.
catatan: ini hanya menghapus ruang, tidak setiap karakter lain yang mungkin dianggap sebagai spasi putih, lihat https://en.cppreference.com/w/cpp/string/byte/isspace
sumber
Menghapus semua karakter spasi putih seperti tab dan jeda baris (C ++ 11):
sumber
output: 2CF4323CB9DE
sumber
sumber
length()
mengembalikan asize_t
, bukan sebuahint
.erase()
mengambilsize_type
, bukanint
. Fungsi ini mungkin akan gagal jika dua spasi berturut-turut ditemukan karena indeks selalu bertambah. Jika satu spasi dihilangkan, maka loop akan membaca di luar batas string. Anda mungkin harus menghapus jawaban ini karena butuh banyak bantuan.Saya khawatir itu solusi terbaik yang bisa saya pikirkan. Tetapi Anda dapat menggunakan cadangan () untuk pra-alokasikan memori minimum yang diperlukan di muka untuk mempercepat segalanya. Anda akan berakhir dengan string baru yang mungkin akan lebih pendek tetapi membutuhkan jumlah memori yang sama, tetapi Anda akan menghindari realokasi.
EDIT: Tergantung pada situasi Anda, ini mungkin menimbulkan lebih sedikit overhead daripada karakter jumbling di sekitar.
Anda harus mencoba berbagai pendekatan dan melihat yang terbaik untuk Anda: Anda mungkin tidak memiliki masalah kinerja sama sekali.
sumber