简体   繁体   中英

Why doesn't my trim function work?

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
}

I want to trim a string of spaces. First I trip spaces from the starting and it works fine and then I find the positions of spaces from the end and try to remove it and it throws exception.

Why?

Changing a string invalidates iterators into the string. One way to fix this would be to modify the string only once. Incidentally, this might also be faster:

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)
}

我建议只是使用boost :: trim

Iterators are only for sure valid until you modify the string. Once you change the string the end iterator surely gets invalidated.

You need to refetch the iterators after each action that could possibly modify the string.

The problem is that you are storing an iterator to the last character in the string and use it only after you have (potentially) erased characters from the string, so the stored iterator is now invalid (not pointing to the last character any more).

It would help to declare variables as close to their first use as possible. In particular, iterators tend to become invalidated so easily, that you should generally avoid holding on to them any longer than necessary.

So, initialize the end iterator after you have erased the leading spaces. (One might also consider removing trailing spaces first.)


May I also suggest using the erase member function for erasing characters from the string.

There may be other errors in erasing trailing whitespace, but you can figure it out when you get there.

str.end() does not refer to any position with the string; hence, if you try to dereference it, you get an exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM