我目前正在使用以下代码在我的程序中右修剪所有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);
它工作得很好,但我想知道是否有一些最终情况下它可能会失败?
当然,有优雅的选择和左修剪解决方案的答案是受欢迎的。
当前回答
下面是一个通道(可能是两个通道)的解决方案。它遍历字符串的空白部分两次,非空白部分一次。
void trim(std::string& s) {
if (s.empty())
return;
int l = 0, r = s.size() - 1;
while (l < s.size() && std::isspace(s[l++])); // l points to first non-whitespace char.
while (r >= 0 && std::isspace(s[r--])); // r points to last non-whitespace char.
if (l > r)
s = "";
else {
l--;
r++;
int wi = 0;
while (l <= r)
s[wi++] = s[l++];
s.erase(wi);
}
return;
}
其他回答
由于添加了back()和pop_back(),这在c++ 11中可以更简单地完成。
while ( !s.empty() && isspace(s.back()) ) s.pop_back();
str.erase(0, str.find_first_not_of("\t\n\v\f\r ")); // left trim
str.erase(str.find_last_not_of("\t\n\v\f\r ") + 1); // right trim
在网上试试!
我不确定您的环境是否相同,但在我的环境中,空字符串情况将导致程序中止。我要么用if(!s.empty())包装这个擦除调用,要么像前面提到的那样使用Boost。
我想如果你开始询问修剪字符串的“最佳方式”,我会说一个好的实现将是:
不分配临时字符串 有过载的地方修剪和复制修剪 可以很容易地定制接受不同的验证序列/逻辑
显然,有太多不同的方法来解决这个问题,这绝对取决于你真正需要什么。然而,C标准库在<string.h>中仍然有一些非常有用的函数,比如memchr。C仍然被认为是IO的最佳语言是有原因的——它的标准库是纯粹的效率。
inline const char* trim_start(const char* str)
{
while (memchr(" \t\n\r", *str, 4)) ++str;
return str;
}
inline const char* trim_end(const char* end)
{
while (memchr(" \t\n\r", end[-1], 4)) --end;
return end;
}
inline std::string trim(const char* buffer, int len) // trim a buffer (input?)
{
return std::string(trim_start(buffer), trim_end(buffer + len));
}
inline void trim_inplace(std::string& str)
{
str.assign(trim_start(str.c_str()),
trim_end(str.c_str() + str.length()));
}
int main()
{
char str [] = "\t \nhello\r \t \n";
string trimmed = trim(str, strlen(str));
cout << "'" << trimmed << "'" << endl;
system("pause");
return 0;
}
c++ 11中还加入了正则表达式模块,当然可以用它来修饰开头或结尾的空格。
也许是这样的:
std::string ltrim(const std::string& s)
{
static const std::regex lws{"^[[:space:]]*", std::regex_constants::extended};
return std::regex_replace(s, lws, "");
}
std::string rtrim(const std::string& s)
{
static const std::regex tws{"[[:space:]]*$", std::regex_constants::extended};
return std::regex_replace(s, tws, "");
}
std::string trim(const std::string& s)
{
return ltrim(rtrim(s));
}