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 &ltrim(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

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

thorough guide for profiling racket code -