我目前正在使用以下代码在我的程序中右修剪所有std::字符串:
std::string s;
s.erase(s.find_last_not_of(" \n\r\t")+1);
它工作得很好,但我想知道是否有一些最终情况下它可能会失败?
当然,有优雅的选择和左修剪解决方案的答案是受欢迎的。
我目前正在使用以下代码在我的程序中右修剪所有std::字符串:
std::string s;
s.erase(s.find_last_not_of(" \n\r\t")+1);
它工作得很好,但我想知道是否有一些最终情况下它可能会失败?
当然,有优雅的选择和左修剪解决方案的答案是受欢迎的。
当前回答
我不确定您的环境是否相同,但在我的环境中,空字符串情况将导致程序中止。我要么用if(!s.empty())包装这个擦除调用,要么像前面提到的那样使用Boost。
其他回答
使用std::find_if_not和反向迭代器(没有+1/-1调整)并返回修剪过的空格数
// returns number of spaces removed
std::size_t RoundTrim(std::string& s)
{
auto const beforeTrim{ s.size() };
auto isSpace{ [](auto const& e) { return std::isspace(e); } };
s.erase(cbegin(s), std::find_if_not(cbegin(s), cend(s), isSpace));
s.erase(std::find_if_not(crbegin(s), crend(s), isSpace).base(), end(s));
return beforeTrim - s.size();
};
我认为在这个例子中使用宏是一个很好的实践:(适用于c++ 98)
#define TRIM_CHARACTERS " \t\n\r\f\v"
#define TRIM_STRING(given) \
given.erase(given.find_last_not_of(TRIM_CHARACTERS) + 1); \
given.erase(0, given.find_first_not_of(TRIM_CHARACTERS));
例子:
#include <iostream>
#include <string>
#define TRIM_CHARACTERS " \t\n\r\f\v"
#define TRIM_STRING(given) \
given.erase(given.find_last_not_of(TRIM_CHARACTERS) + 1); \
given.erase(0, given.find_first_not_of(TRIM_CHARACTERS));
int main(void) {
std::string text(" hello world!! \t \r");
TRIM_STRING(text);
std::cout << text; // "hello world!!"
}
修剪两端。
string trim(const std::string &str){
string result = "";
size_t endIndex = str.size();
while (endIndex > 0 && isblank(str[endIndex-1]))
endIndex -= 1;
for (size_t i=0; i<endIndex ; i+=1){
char ch = str[i];
if (!isblank(ch) || result.size()>0)
result += ch;
}
return result;
}
我知道这是一个非常老的问题,但我已经为您的问题添加了几行代码,它从两端删除了空白。
void trim(std::string &line){
auto val = line.find_last_not_of(" \n\r\t") + 1;
if(val == line.size() || val == std::string::npos){
val = line.find_first_not_of(" \n\r\t");
line = line.substr(val);
}
else
line.erase(val);
}
一种优雅的方法可以是
std::string & trim(std::string & str)
{
return ltrim(rtrim(str));
}
支持功能实现为:
std::string & ltrim(std::string & str)
{
auto it = std::find_if( str.begin() , str.end() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
str.erase( str.begin() , it);
return str;
}
std::string & rtrim(std::string & str)
{
auto it = std::find_if( str.rbegin() , str.rend() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
str.erase( it.base() , str.end() );
return str;
}
一旦你把这些都准备好了,你也可以这样写:
std::string trim_copy(std::string const & str)
{
auto s = str;
return ltrim(rtrim(s));
}