我目前正在使用以下代码右键修剪程序中的所有std::strings:
std::string s;
s、 擦除(s.find_last_not_of(“\n\r\t”)+1);
它工作得很好,但我想知道是否有一些最终案例可能会失败
当然,也欢迎使用优雅的备选方案和左饰解决方案
编辑自c++17以来,标准库的某些部分被删除。幸运的是,从c++11开始,我们有了lambdas,这是一个更好的解决方案
#包括<;算法>;
#包括<;cctype>;
#包括<;地点>;
//从开始修剪(就地)
静态内联void ltrim(标准::字符串&;s){
s、 擦除(s.begin(),std::find_if(s.begin(),s.end(),[])(无符号字符){
return!std::isspace(ch);
}));
}
//从末端修剪(到位)
静态内联void rtrim(标准::字符串和s){
s、 擦除(std::find_if(s.rbegin(),s.rend(),[](未签名字符){
return!std::isspace(ch);
}).base(),s.end());
}
//两端修剪(到位)
静态内嵌空隙修剪(标准::字符串和s){
ltrim(s),;
rtrim(s),;
}
//从开始修剪(复制)
静态内联std::string ltrim\u拷贝(std::string s){
ltrim(s),;
返回s;
}
//从末端修剪(复制)
静态内联std::string rtrim\u拷贝(std::string s){
rtrim(s),;
返回s;
}
//从两端修剪(复制)
静态内联标准::字符串修剪\复制(标准::字符串s){
修剪;
返回s;
}
多亏了https://stackoverflow.com/a/44973498/524503 提出现代解决方案
原始答复:
我倾向于使用以下三种方法之一来满足修剪需求:
#包括<;算法>;
#包括<;功能性>;
#包括<;cctype>;
#包括<;地点>;
//从头修剪
静态内联std::string&;ltrim(标准:字符串和s){
s、 擦除(s.begin(),std::find_if(s.begin(),s.end(),
std::not1(std::ptr_fun<;int,int>;(std::isspace));
返回s;
}
//从末端修剪
静态内联std::string&;rtrim(标准:字符串和s){
s、 擦除(std::find_if(s.rbegin(),s.rend(),
std::not1(std::ptr_-fun<;int,int>;(std::isspace)).base(),s.end();
返回s;
}
//两端修剪
静态内联std::string&;修剪(标准:字符串和s){
返回ltrim(rtrim);
}
它们是相当不言自明的,并且工作得非常好
EDIT:顺便说一句,我有std::ptr_fun来帮助消除std::isspace的歧义,因为实际上还有第二个定义支持区域设置。这本可以是一个演员阵容,但我更喜欢这个
编辑:处理有关通过引用接受参数、修改和返回参数的一些注释。我同意。我可能更喜欢的实现是两组函数,一组用于就地,另一组用于复制。更好的例子是:
#包括<;算法>;
#包括<;功能性>;
#包括<;cctype>;
#包括<;地点>;
//从开始修剪(就地)
静态内联void ltrim(标准::字符串&;s){
s、 擦除(s.begin(),std::find_if(s.begin(),s.end(),
std::not1(std::ptr_fun<;int,int>;(std::isspace));
}
//从末端修剪(到位)
静态内联void rtrim(标准::字符串和s){
s、 擦除(std::find_if(s.rbegin(),s.rend(),
std::not1(std::ptr_-fun<;int,int>;(std::isspace)).base(),s.end();
}
//两端修剪(到位)
静态内嵌空隙修剪(标准::字符串和s){
ltrim(s),;
rtrim(s),;
}
//从开始修剪(复制)
静态内联std::string ltrim\u拷贝(std::string s){
ltrim(s),;
返回s;
}
//从末端修剪(复制)
静态内联std::string rtrim\u拷贝(std::string s){
rtrim(s),;
返回s;
}
//从两端修剪(复制)
静态内联标准::字符串修剪\复制(标准::字符串s){
修剪;
返回s;
}
我保留了上面的原始答案,但出于上下文考虑,为了保持高投票率的答案仍然可用