我目前正在使用以下代码在我的程序中右修剪所有std::字符串:

std::string s;
s.erase(s.find_last_not_of(" \n\r\t")+1);

它工作得很好,但我想知道是否有一些最终情况下它可能会失败?

当然,有优雅的选择和左修剪解决方案的答案是受欢迎的。


当前回答

我已经阅读了大部分答案,但没有发现任何人使用istringstream

std::string text = "Let me split this into words";

std::istringstream iss(text);
std::vector<std::string> results((std::istream_iterator<std::string>(iss)),
                                 std::istream_iterator<std::string>());

结果是单词的向量,它可以处理有内部空白的字符串,希望这有帮助。

其他回答

有点晚了,不过没关系。c++ 11在这里,我们有lambda和auto变量。所以我的版本,也处理全空白和空字符串,是:

#include <cctype>
#include <string>
#include <algorithm>

inline std::string trim(const std::string &s)
{
   auto wsfront=std::find_if_not(s.begin(),s.end(),[](int c){return std::isspace(c);});
   auto wsback=std::find_if_not(s.rbegin(),s.rend(),[](int c){return std::isspace(c);}).base();
   return (wsback<=wsfront ? std::string() : std::string(wsfront,wsback));
}

我们可以从wsfront创建一个反向迭代器,并在第二个find_if_not中使用它作为终止条件,但这只在全空白字符串的情况下有用,gcc 4.8至少不足以用auto推断反向迭代器(std::string::const_reverse_iterator)的类型。我不知道构造反向迭代器有多贵,这里是YMMV。修改后,代码如下所示:

inline std::string trim(const std::string &s)
{
   auto  wsfront=std::find_if_not(s.begin(),s.end(),[](int c){return std::isspace(c);});
   return std::string(wsfront,std::find_if_not(s.rbegin(),std::string::const_reverse_iterator(wsfront),[](int c){return std::isspace(c);}).base());
}
std::string trim( std::string && str )
{
    size_t end = str.find_last_not_of( " \n\r\t" );
    if ( end != std::string::npos )
        str.resize( end + 1 );

    size_t start = str.find_first_not_of( " \n\r\t" );
    if ( start != std::string::npos )
        str = str.substr( start );

    return std::move( str );
}

这就是我用的。继续把前面的空格去掉,然后,如果还有剩余的,从后面也这样做。

void trim(string& s) {
    while(s.compare(0,1," ")==0)
        s.erase(s.begin()); // remove leading whitespaces
    while(s.size()>0 && s.compare(s.size()-1,1," ")==0)
        s.erase(s.end()-1); // remove trailing whitespaces
}

我用的是这个:

void trim(string &str){
    int i=0;

    //left trim
    while (isspace(str[i])!=0)
        i++;
    str = str.substr(i,str.length()-i);

    //right trim
    i=str.length()-1;
    while (isspace(str[i])!=0)
        i--;
    str = str.substr(0,i+1);
}

因为我想用c++ 11的方法更新我的旧c++修剪函数,我已经测试了很多关于这个问题的答案。我的结论是,我保留了旧的c++解决方案!

它是总体上最快的一个,即使添加更多的字符来检查(例如\r\n我没有看到\f\v的用例)仍然比使用算法的解决方案更快。

std::string & trimMe (std::string & str)
{
   // right trim
   while (str.length () > 0 && (str [str.length ()-1] == ' ' || str [str.length ()-1] == '\t'))
      str.erase (str.length ()-1, 1);

   // left trim
   while (str.length () > 0 && (str [0] == ' ' || str [0] == '\t'))
      str.erase (0, 1);
   return str;
}