我目前正在使用以下代码在我的程序中右修剪所有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 char* ws = " \t\n\r\f\v";
// trim from end of string (right)
inline std::string& rtrim(std::string& s, const char* t = ws)
{
s.erase(s.find_last_not_of(t) + 1);
return s;
}
// trim from beginning of string (left)
inline std::string& ltrim(std::string& s, const char* t = ws)
{
s.erase(0, s.find_first_not_of(t));
return s;
}
// trim from both ends of string (right then left)
inline std::string& trim(std::string& s, const char* t = ws)
{
return ltrim(rtrim(s, t), t);
}
通过提供要修剪的字符,您可以灵活地修剪非空白字符,并高效地只修剪您想修剪的字符。
其他回答
在空字符串的情况下,你的代码假设将1添加到string::npos得到0。String::npos的类型是String::size_type,无符号。因此,您依赖于加法的溢出行为。
这里有一个容易理解的解决方案,初学者不习惯编写std::无处不在,还不熟悉常量正确性,迭代器,STL算法等…
#include <string>
#include <cctype> // for isspace
using namespace std;
// Left trim the given string (" hello! " --> "hello! ")
string left_trim(string str) {
int numStartSpaces = 0;
for (int i = 0; i < str.length(); i++) {
if (!isspace(str[i])) break;
numStartSpaces++;
}
return str.substr(numStartSpaces);
}
// Right trim the given string (" hello! " --> " hello!")
string right_trim(string str) {
int numEndSpaces = 0;
for (int i = str.length() - 1; i >= 0; i--) {
if (!isspace(str[i])) break;
numEndSpaces++;
}
return str.substr(0, str.length() - numEndSpaces);
}
// Left and right trim the given string (" hello! " --> "hello!")
string trim(string str) {
return right_trim(left_trim(str));
}
希望能有所帮助……
修剪两端。
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;
}
使用Boost的字符串算法是最简单的:
#include <boost/algorithm/string.hpp>
std::string str("hello world! ");
boost::trim_right(str);
STR现在是"hello world!"。还有trim_left和trim,它们修剪两边。
如果你给上面的函数名加上_copy后缀,例如trim_copy,函数将返回一个经过修剪的字符串副本,而不是通过引用修改它。
如果你给上面的任何函数名加上_if后缀,例如trim_copy_if,你可以修剪所有满足自定义谓词的字符,而不是只有空白。
穷人的绳子装饰(仅限空格):
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);
}