Cara menghapus spasi dari objek string di C ++.
Misalnya, cara menghapus spasi di depan dan di belakang dari objek string di bawah ini.
//Original string: " This is a sample string "
//Desired string: "This is a sample string"
Kelas string, sejauh yang saya tahu, tidak menyediakan metode apa pun untuk menghapus spasi di depan dan di belakang.
Untuk menambah masalah, bagaimana memperluas pemformatan ini untuk memproses spasi ekstra di antara kata-kata dalam string. Sebagai contoh,
// Original string: " This is a sample string "
// Desired string: "This is a sample string"
Dengan menggunakan metode string yang disebutkan dalam solusi, saya dapat memikirkan melakukan operasi ini dalam dua langkah.
- Hapus spasi di depan dan di belakang.
- Gunakan find_first_of, find_last_of, find_first_not_of, find_last_not_of dan substr , berulang kali pada batas kata untuk mendapatkan format yang diinginkan.
site_t
menjadisize_t
? Dan saya pikir di mana Anda memiliki komentarno whitespace
berarti string itu semua spasi atau kosong.size_t
kesalahan ketik dan off-by-one dalam pengeditan, tetapi tidak melihat komentar saya terbalik, terima kasih.Mudah menghapus spasi di depan, di belakang, dan ekstra dari string std :: dalam satu baris
value = std::regex_replace(value, std::regex("^ +| +$|( ) +"), "$1");
menghapus hanya spasi di depan
value.erase(value.begin(), std::find_if(value.begin(), value.end(), std::bind1st(std::not_equal_to<char>(), ' ')));
atau
value = std::regex_replace(value, std::regex("^ +"), "");
menghapus hanya spasi tertinggal
value.erase(std::find_if(value.rbegin(), value.rend(), std::bind1st(std::not_equal_to<char>(), ' ')).base(), value.end());
atau
value = std::regex_replace(value, std::regex(" +$"), "");
menghapus hanya spasi ekstra
value = regex_replace(value, std::regex(" +"), " ");
sumber
substr
atauerase
).Saya saat ini menggunakan fungsi-fungsi ini:
// trim from left inline std::string& ltrim(std::string& s, const char* t = " \t\n\r\f\v") { s.erase(0, s.find_first_not_of(t)); return s; } // trim from right inline std::string& rtrim(std::string& s, const char* t = " \t\n\r\f\v") { s.erase(s.find_last_not_of(t) + 1); return s; } // trim from left & right inline std::string& trim(std::string& s, const char* t = " \t\n\r\f\v") { return ltrim(rtrim(s, t), t); } // copying versions inline std::string ltrim_copy(std::string s, const char* t = " \t\n\r\f\v") { return ltrim(s, t); } inline std::string rtrim_copy(std::string s, const char* t = " \t\n\r\f\v") { return rtrim(s, t); } inline std::string trim_copy(std::string s, const char* t = " \t\n\r\f\v") { return trim(s, t); }
sumber
Tingkatkan algoritme pemangkasan string
#include <boost/algorithm/string/trim.hpp> [...] std::string msg = " some text with spaces "; boost::algorithm::trim(msg);
sumber
Ini adalah solusi saya untuk menghilangkan ruang depan dan belakang ...
std::string stripString = " Plamen "; while(!stripString.empty() && std::isspace(*stripString.begin())) stripString.erase(stripString.begin()); while(!stripString.empty() && std::isspace(*stripString.rbegin())) stripString.erase(stripString.length()-1);
Hasilnya adalah "Plamen"
sumber
Inilah cara Anda melakukannya:
std::string & trim(std::string & str) { return ltrim(rtrim(str)); }
Dan fungsi pendukung diimplementasikan sebagai:
std::string & ltrim(std::string & str) { auto it2 = std::find_if( str.begin() , str.end() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } ); str.erase( str.begin() , it2); return str; } std::string & rtrim(std::string & str) { auto it1 = std::find_if( str.rbegin() , str.rend() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } ); str.erase( it1.base() , str.end() ); return str; }
Dan setelah Anda memiliki semua ini, Anda juga dapat menulis ini:
std::string trim_copy(std::string const & str) { auto s = str; return ltrim(rtrim(s)); }
Coba ini
sumber
Contoh untuk memangkas spasi di depan dan di belakang mengikuti saran jon-hanson untuk menggunakan dorongan (hanya menghapus spasi di belakang dan di belakang):
#include <boost/algorithm/string/trim.hpp> std::string str = " t e s t "; boost::algorithm::trim ( str );
Hasil dalam
"t e s t"
Ada juga
trim_left
menghasilkan"t e s t "
trim_right
menghasilkan" t e s t"
sumber
/// strip a string, remove leading and trailing spaces void strip(const string& in, string& out) { string::const_iterator b = in.begin(), e = in.end(); // skipping leading spaces while (isSpace(*b)){ ++b; } if (b != e){ // skipping trailing spaces while (isSpace(*(e-1))){ --e; } } out.assign(b, e); }
Pada kode di atas, fungsi isSpace () adalah fungsi boolean yang memberitahukan apakah suatu karakter adalah spasi putih, Anda dapat mengimplementasikan fungsi ini untuk mencerminkan kebutuhan Anda, atau cukup memanggil isspace () dari "ctype.h" jika Anda mau .
sumber
Contoh untuk memotong spasi di depan dan di belakang
std::string aString(" This is a string to be trimmed "); auto start = aString.find_first_not_of(' '); auto end = aString.find_last_not_of(' '); std::string trimmedString; trimmedString = aString.substr(start, (end - start) + 1);
ATAU
trimmedSring = aString.substr(aString.find_first_not_of(' '), (aString.find_last_not_of(' ') - aString.find_first_not_of(' ')) + 1);
sumber
Menggunakan pustaka standar memiliki banyak manfaat, tetapi orang harus menyadari beberapa kasus khusus yang menyebabkan pengecualian. Misalnya, tidak ada jawaban yang mencakup kasus di mana string C ++ memiliki beberapa karakter Unicode. Dalam kasus ini, jika Anda menggunakan fungsi isspace , pengecualian akan muncul.
Saya telah menggunakan kode berikut untuk memotong string dan beberapa operasi lain yang mungkin berguna. Manfaat utama kode ini adalah: sangat cepat (lebih cepat daripada kode apa pun yang pernah saya uji), hanya menggunakan pustaka standar, dan tidak pernah menyebabkan pengecualian:
#include <string> #include <algorithm> #include <functional> #include <locale> #include <iostream> typedef unsigned char BYTE; std::string strTrim(std::string s, char option = 0) { // convert all whitespace characters to a standard space std::replace_if(s.begin(), s.end(), (std::function<int(BYTE)>)::isspace, ' '); // remove leading and trailing spaces size_t f = s.find_first_not_of(' '); if (f == std::string::npos) return ""; s = s.substr(f, s.find_last_not_of(' ') - f + 1); // remove consecutive spaces s = std::string(s.begin(), std::unique(s.begin(), s.end(), [](BYTE l, BYTE r){ return l == ' ' && r == ' '; })); switch (option) { case 'l': // convert to lowercase std::transform(s.begin(), s.end(), s.begin(), ::tolower); return s; case 'U': // convert to uppercase std::transform(s.begin(), s.end(), s.begin(), ::toupper); return s; case 'n': // remove all spaces s.erase(std::remove(s.begin(), s.end(), ' '), s.end()); return s; default: // just trim return s; } }
sumber
Ini mungkin yang paling sederhana dari semuanya.
Anda dapat menggunakan
string::find
danstring::rfind
untuk menemukan spasi dari kedua sisi dan mengurangi string.void TrimWord(std::string& word) { if (word.empty()) return; // Trim spaces from left side while (word.find(" ") == 0) { word.erase(0, 1); } // Trim spaces from right side size_t len = word.size(); while (word.rfind(" ") == --len) { word.erase(len, len + 1); } }
sumber
Saya sudah menguji ini, semuanya berhasil. Jadi metode processInput ini hanya akan meminta pengguna untuk mengetikkan sesuatu. Ini akan mengembalikan string yang tidak memiliki spasi ekstra secara internal, atau spasi ekstra di awal atau akhir. Semoga ini membantu. (juga beri banyak komentar agar mudah dipahami).
Anda bisa melihat bagaimana menerapkannya di main () di bagian bawah
#include <string> #include <iostream> string processInput() { char inputChar[256]; string output = ""; int outputLength = 0; bool space = false; // user inputs a string.. well a char array cin.getline(inputChar,256); output = inputChar; string outputToLower = ""; // put characters to lower and reduce spaces for(int i = 0; i < output.length(); i++){ // if it's caps put it to lowercase output[i] = tolower(output[i]); // make sure we do not include tabs or line returns or weird symbol for null entry array thingy if (output[i] != '\t' && output[i] != '\n' && output[i] != 'Ì') { if (space) { // if the previous space was a space but this one is not, then space now is false and add char if (output[i] != ' ') { space = false; // add the char outputToLower+=output[i]; } } else { // if space is false, make it true if the char is a space if (output[i] == ' ') { space = true; } // add the char outputToLower+=output[i]; } } } // trim leading and tailing space string trimmedOutput = ""; for(int i = 0; i < outputToLower.length(); i++){ // if it's the last character and it's not a space, then add it // if it's the first character and it's not a space, then add it // if it's not the first or the last then add it if (i == outputToLower.length() - 1 && outputToLower[i] != ' ' || i == 0 && outputToLower[i] != ' ' || i > 0 && i < outputToLower.length() - 1) { trimmedOutput += outputToLower[i]; } } // return output = trimmedOutput; return output; } int main() { cout << "Username: "; string userName = processInput(); cout << "\nModified Input = " << userName << endl; }
sumber
Mengapa mempersulit?
std::string removeSpaces(std::string x){ if(x[0] == ' ') { x.erase(0, 1); return removeSpaces(x); } if(x[x.length() - 1] == ' ') { x.erase(x.length() - 1, x.length()); return removeSpaces(x); } else return x; }
Ini berfungsi bahkan jika peningkatan gagal, tidak ada regex, tidak ada hal-hal aneh atau pustaka.
EDIT: Perbaiki untuk komentar MM.
sumber
C ++ 17 diperkenalkan
std::basic_string_view
, template kelas yang mengacu pada urutan berdekatan konstan dari objek seperti karakter, yaitu tampilan string. Selain memiliki antarmuka yang sangat miripstd::basic_string
, ia memiliki dua fungsi tambahanremove_prefix()
:, yang mengecilkan tampilan dengan menggerakkan awalnya; danremove_suffix()
, yang mengecilkan tampilan dengan menggerakkan ujungnya ke belakang. Ini dapat digunakan untuk memangkas ruang depan dan belakang:#include <string_view> #include <string> std::string_view ltrim(std::string_view str) { const auto pos(str.find_first_not_of(" \t")); str.remove_prefix(pos); return str; } std::string_view rtrim(std::string_view str) { const auto pos(str.find_last_not_of(" \t")); str.remove_suffix(str.length() - pos - 1); return str; } std::string_view trim(std::string_view str) { str = ltrim(str); str = rtrim(str); return str; } int main() { std::string str = " hello world "; auto sv1{ ltrim(str) }; // "hello world " auto sv2{ rtrim(str) }; // " hello world" auto sv3{ trim(str) }; // "hello world" //If you want, you can create std::string objects from std::string_view objects auto s1{ sv1 }; auto s2{ sv2 }; auto s3{ sv3 }; }
Catatan: the
std::string_view
adalah referensi non-pemilik, jadi ini hanya valid selama string aslinya masih ada.sumber
char *str = (char*) malloc(50 * sizeof(char)); strcpy(str, " some random string (<50 chars) "); while(*str == ' ' || *str == '\t' || *str == '\n') str++; int len = strlen(str); while(len >= 0 && (str[len - 1] == ' ' || str[len - 1] == '\t' || *str == '\n') { *(str + len - 1) = '\0'; len--; } printf(":%s:\n", str);
sumber
void removeSpaces(string& str) { /* remove multiple spaces */ int k=0; for (int j=0; j<str.size(); ++j) { if ( (str[j] != ' ') || (str[j] == ' ' && str[j+1] != ' ' )) { str [k] = str [j]; ++k; } } str.resize(k); /* remove space at the end */ if (str [k-1] == ' ') str.erase(str.end()-1); /* remove space at the begin */ if (str [0] == ' ') str.erase(str.begin()); }
sumber
string trim(const string & sStr) { int nSize = sStr.size(); int nSPos = 0, nEPos = 1, i; for(i = 0; i< nSize; ++i) { if( !isspace( sStr[i] ) ) { nSPos = i ; break; } } for(i = nSize -1 ; i >= 0 ; --i) { if( !isspace( sStr[i] ) ) { nEPos = i; break; } } return string(sStr, nSPos, nEPos - nSPos + 1); }
sumber
Untuk spasi di depan dan di belakang, bagaimana dengan:
string string_trim(const string& in) { stringstream ss; string out; ss << in; ss >> out; return out; }
Atau untuk kalimat:
string trim_words(const string& sentence) { stringstream ss; ss << sentence; string s; string out; while(ss >> s) { out+=(s+' '); } return out.substr(0, out.length()-1); }
sumber
void trimLeftTrailingSpaces(string &input) { input.erase(input.begin(), find_if(input.begin(), input.end(), [](int ch) { return !isspace(ch); })); } void trimRightTrailingSpaces(string &input) { input.erase(find_if(input.rbegin(), input.rend(), [](int ch) { return !isspace(ch); }).base(), input.end()); }
sumber
Tidak
boost
, tidakregex
, hanyastring
perpustakaan. Sesederhana itu.string trim(const string s) { // removes whitespace characters from beginnig and end of string s const int l = (int)s.length(); int a=0, b=l-1; char c; while(a<l && ((c=s.at(a))==' '||c=='\t'||c=='\n'||c=='\v'||c=='\f'||c=='\r'||c=='\0')) a++; while(b>a && ((c=s.at(b))==' '||c=='\t'||c=='\n'||c=='\v'||c=='\f'||c=='\r'||c=='\0')) b--; return s.substr(a, 1+b-a); }
sumber
Sebenarnya, ini adalah kasus yang lebih sederhana daripada memperhitungkan beberapa karakter spasi kosong di depan dan di belakang. Yang perlu Anda lakukan adalah menghapus karakter spasi putih duplikat yang berdekatan dari seluruh string.
Predikat untuk white space yang berdekatan adalah:
auto by_space = [](unsigned char a, unsigned char b) { return std::isspace(a) and std::isspace(b); };
lalu Anda dapat membuang duplikat karakter spasi-putih yang berdekatan itu dengan
std::unique
, dan idiom hapus-hapus:// s = " This is a sample string " s.erase(std::unique(std::begin(s), std::end(s), by_space), std::end(s)); // s = " This is a sample string "
Ini berpotensi meninggalkan karakter spasi kosong ekstra di depan dan / atau belakang. Ini dapat dihapus dengan mudah:
if (std::size(s) && std::isspace(s.back())) s.pop_back(); if (std::size(s) && std::isspace(s.front())) s.erase(0, 1);
Berikut demo nya .
sumber
Solusi saya untuk masalah ini tidak menggunakan metode STL tetapi hanya metode string C ++ sendiri adalah sebagai berikut:
void processString(string &s) { if ( s.empty() ) return; //delete leading and trailing spaces of the input string int notSpaceStartPos = 0, notSpaceEndPos = s.length() - 1; while ( s[notSpaceStartPos] == ' ' ) ++notSpaceStartPos; while ( s[notSpaceEndPos] == ' ' ) --notSpaceEndPos; if ( notSpaceStartPos > notSpaceEndPos ) { s = ""; return; } s = s.substr(notSpaceStartPos, notSpaceEndPos - notSpaceStartPos + 1); //reduce multiple spaces between two words to a single space string temp; for ( int i = 0; i < s.length(); i++ ) { if ( i > 0 && s[i] == ' ' && s[i-1] == ' ' ) continue; temp.push_back(s[i]); } s = temp; }
Saya telah menggunakan metode ini untuk melewati masalah LeetCode Kata Terbalik dalam String
sumber
void TrimWhitespaces(std::wstring& str) { if (str.empty()) return; const std::wstring& whitespace = L" \t"; std::wstring::size_type strBegin = str.find_first_not_of(whitespace); std::wstring::size_type strEnd = str.find_last_not_of(whitespace); if (strBegin != std::wstring::npos || strEnd != std::wstring::npos) { strBegin == std::wstring::npos ? 0 : strBegin; strEnd == std::wstring::npos ? str.size() : 0; const auto strRange = strEnd - strBegin + 1; str.substr(strBegin, strRange).swap(str); } else if (str[0] == ' ' || str[0] == '\t') // handles non-empty spaces-only or tabs-only { str = L""; } } void TrimWhitespacesTest() { std::wstring EmptyStr = L""; std::wstring SpacesOnlyStr = L" "; std::wstring TabsOnlyStr = L" "; std::wstring RightSpacesStr = L"12345 "; std::wstring LeftSpacesStr = L" 12345"; std::wstring NoSpacesStr = L"12345"; TrimWhitespaces(EmptyStr); TrimWhitespaces(SpacesOnlyStr); TrimWhitespaces(TabsOnlyStr); TrimWhitespaces(RightSpacesStr); TrimWhitespaces(LeftSpacesStr); TrimWhitespaces(NoSpacesStr); assert(EmptyStr == L""); assert(SpacesOnlyStr == L""); assert(TabsOnlyStr == L""); assert(RightSpacesStr == L"12345"); assert(LeftSpacesStr == L"12345"); assert(NoSpacesStr == L"12345"); }
sumber
Bagaimana dengan idiom hapus-hapus ?
std::string s("..."); s.erase( std::remove(s.begin(), s.end(), ' '), s.end() );
Maaf. Saya terlambat melihat bahwa Anda tidak ingin menghapus semua spasi.
sumber