为什么我的装饰功能不起作用?

时间:2010-08-20 09:43:09

标签: c++ string

void trim(string &str)
{
    string::iterator it = str.begin();
    string::iterator end = str.end() - 1;

    // trim at the starting
    for(; it != str.end() && isspace(*it); it++)
        ;
    str.replace(str.begin(), it, "");

    // trim at the end
    for(; end >= str.begin() && isspace(*end); end--)
        ;
    str.replace(str.end(), end, ""); // i get the out_of_range exception here
}

我想修剪一串空格。首先我从起点开始行程并且它工作正常,然后我从末尾找到空格的位置并尝试将其删除,它会抛出异常。

为什么?

5 个答案:

答案 0 :(得分:7)

将字符串 更改为迭代器 到字符串中。解决此问题的一种方法是仅修改字符串一次。顺便说一下,这也可能更快:

void trim(std::string &str)
{
    std::string::size_type begin=0;
    while(begin<str.size() && isspace(str[begin]))
      ++begin;
    std::string::size_type end=str.size()-1;
    while(end>begin && isspace(str[end]))
      --end;
    str = str.substr(begin, end - begin + 1)
}

答案 1 :(得分:3)

我建议只使用boost::trim

答案 2 :(得分:2)

在修改字符串之前,迭代器肯定有效。一旦你改变了字符串,结束迭代器肯定会失效。

您需要在每次可能修改字符串的操作后重新获取迭代器。

答案 3 :(得分:0)

问题是你将迭代器存储到字符串中的最后一个字符,并且只有在你有(可能)删除字符串中的字符后才使用它,所以存储的迭代器现在无效(不指向最后一个字符)更多)。

将变量声明为尽可能接近第一次使用是有帮助的。特别是,迭代器很容易变得无效,你通常应该避免使用它们。

因此,在擦除前导空格后初始化结束迭代器。 (人们也可以考虑先删除尾随空格。)


我还建议使用erase成员函数来删除字符串中的字符。

在删除尾随空格时可能还有其他错误,但是当你到达那里时你可以弄明白。

答案 4 :(得分:-1)

str.end()不引用任何带字符串的位置;因此,如果你试图取消引用它,你会得到一个例外。

相关问题