我目前正在使用以下代码在我的程序中右修剪所有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);
它工作得很好,但我想知道是否有一些最终情况下它可能会失败?
当然,有优雅的选择和左修剪解决方案的答案是受欢迎的。
当前回答
我的解决方案是基于@比尔蜥蜴的回答。
注意,如果输入字符串只包含空格,这些函数将返回空字符串。
const std::string StringUtils::WHITESPACE = " \n\r\t";
std::string StringUtils::Trim(const std::string& s)
{
return TrimRight(TrimLeft(s));
}
std::string StringUtils::TrimLeft(const std::string& s)
{
size_t startpos = s.find_first_not_of(StringUtils::WHITESPACE);
return (startpos == std::string::npos) ? "" : s.substr(startpos);
}
std::string StringUtils::TrimRight(const std::string& s)
{
size_t endpos = s.find_last_not_of(StringUtils::WHITESPACE);
return (endpos == std::string::npos) ? "" : s.substr(0, endpos+1);
}
其他回答
修剪两端。
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;
}
下面是一个简单的实现。对于这样一个简单的操作,您可能不应该使用任何特殊的构造。内置的isspace()函数负责处理各种形式的白色字符,因此我们应该充分利用它。您还必须考虑字符串为空或只是一堆空格的特殊情况。向左或向右修剪可以从下面的代码派生。
string trimSpace(const string &str) {
if (str.empty()) return str;
string::size_type i,j;
i=0;
while (i<str.size() && isspace(str[i])) ++i;
if (i == str.size())
return string(); // empty string
j = str.size() - 1;
//while (j>0 && isspace(str[j])) --j; // the j>0 check is not needed
while (isspace(str[j])) --j
return str.substr(i, j-i+1);
}
C++11:
int i{};
string s = " h e ll \t\n o";
string trim = " \n\t";
while ((i = s.find_first_of(trim)) != -1)
s.erase(i,1);
cout << s;
输出:
hello
也适用于空字符串
穷人的绳子装饰(仅限空格):
std::string trimSpaces(const std::string& str)
{
int start, len;
for (start = 0; start < str.size() && str[start] == ' '; start++);
for (len = str.size() - start; len > 0 && str[start + len - 1] == ' '; len--);
return str.substr(start, len);
}
在c++ 17中,你可以使用basic_string_view::remove_prefix和basic_string_view::remove_suffix:
std::string_view trim(std::string_view s)
{
s.remove_prefix(std::min(s.find_first_not_of(" \t\r\v\n"), s.size()));
s.remove_suffix(std::min(s.size() - s.find_last_not_of(" \t\r\v\n") - 1, s.size()));
return s;
}
一个不错的替代方案:
std::string_view ltrim(std::string_view s)
{
s.remove_prefix(std::distance(s.cbegin(), std::find_if(s.cbegin(), s.cend(),
[](int c) {return !std::isspace(c);})));
return s;
}
std::string_view rtrim(std::string_view s)
{
s.remove_suffix(std::distance(s.crbegin(), std::find_if(s.crbegin(), s.crend(),
[](int c) {return !std::isspace(c);})));
return s;
}
std::string_view trim(std::string_view s)
{
return ltrim(rtrim(s));
}