c++ - What's the best way to trim std::string? -
i'm using following code right-trim std::strings
in programs:
std::string s; s.erase(s.find_last_not_of(" \n\r\t")+1);
it works fine, wonder if there end-cases might fail?
of course, answers elegant alternatives , left-trim solution welcome.
edit since c++17, parts of standard library removed. fortunately, starting c++11, have lambdas superior solution.
#include <algorithm> #include <cctype> #include <locale> // trim start (in place) static inline void ltrim(std::string &s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) { return !std::isspace(ch); })); } // trim end (in place) static inline void rtrim(std::string &s) { s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) { return !std::isspace(ch); }).base(), s.end()); } // trim both ends (in place) static inline void trim(std::string &s) { ltrim(s); rtrim(s); } // trim start (copying) static inline std::string ltrim_copy(std::string s) { ltrim(s); return s; } // trim end (copying) static inline std::string rtrim_copy(std::string s) { rtrim(s); return s; } // trim both ends (copying) static inline std::string trim_copy(std::string s) { trim(s); return s; }
thanks https://stackoverflow.com/a/44973498/524503 bringing modern solution.
original answer:
i tend use 1 of these 3 trimming needs:
#include <algorithm> #include <functional> #include <cctype> #include <locale> // trim start static inline std::string <rim(std::string &s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace)))); return s; } // trim end static inline std::string &rtrim(std::string &s) { s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end()); return s; } // trim both ends static inline std::string &trim(std::string &s) { return ltrim(rtrim(s)); }
they self explanatory , work well.
edit: btw, have std::ptr_fun
in there disambiguate std::isspace
because there second definition supports locales. have been cast same, tend better.
edit: address comments accepting parameter reference, modifying , returning it. agree. implementation prefer 2 sets of functions, 1 in place , 1 makes copy. better set of examples be:
#include <algorithm> #include <functional> #include <cctype> #include <locale> // trim start (in place) static inline void ltrim(std::string &s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace)))); } // trim end (in place) static inline void rtrim(std::string &s) { s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end()); } // trim both ends (in place) static inline void trim(std::string &s) { ltrim(s); rtrim(s); } // trim start (copying) static inline std::string ltrim_copy(std::string s) { ltrim(s); return s; } // trim end (copying) static inline std::string rtrim_copy(std::string s) { rtrim(s); return s; } // trim both ends (copying) static inline std::string trim_copy(std::string s) { trim(s); return s; }
i keeping original answer above though context , in interest of keeping high voted answer still available.
Comments
Post a Comment