代码之家  ›  专栏  ›  技术社区  ›  jkeys

表达式:字符串迭代器不可取消引用

  •  0
  • jkeys  · 技术社区  · 17 年前

    我很难使用STD::String:C++中的迭代器。这段代码在Dev-C++中编译得很好(仍然没有得到正确的输出,但这是我的错:TODO,fix算法),并且我没有遇到运行时错误。错误是VisualStudioExpress 2008 C++,其中我指向一个错误指向lt;xstring>:“表达式:字符串迭代器不可解引用”,并指向<xstring>文件

    std::string wordWrap(std::string sentence, int width)
    {    
        std::string::iterator it = sentence.begin();
    
        //remember how long next word is
        int nextWordLength = 0;
        int distanceFromWidth = width;
    
        while (it < sentence.end())
        {
           while (*it != ' ' && it != sentence.end())
           {
              nextWordLength++;
              distanceFromWidth--;
              it++;
           }
    
           if (nextWordLength > distanceFromWidth)
           {
              *it = '\n';
              distanceFromWidth = width;
              nextWordLength = 0;
           }
    
           //skip the space
           it++;
    
       }
    
       return sentence;    
    }
    
    3 回复  |  直到 17 年前
        1
  •  15
  •   David Rodríguez - dribeas    17 年前

    首先,使用操作符=()在迭代器上,而不是运算符上<():

    while (it != sentence.end())
    

    第二,这是倒退: while (*it != ' ' && it != sentence.end())

    使用迭代器执行某些操作,然后检查迭代器是否有效。相反,您应该首先检查它是否有效:

    while (it != sentence.end() && *it != ' ')
    


    第四,这里有一个主要问题:

    *it = '\n';
    

    因为之前的检查, while (it != sentence.end() ,可以在结束时达到迭代器解引用。解决方法是:

    if (it != sentence.end() && nextWordLength > distanceFromWidth)
    

    所以现在如果你已经到了终点,你就停下来。


    在修复之前的问题后,现在唯一的问题是:

    //skip the space
    ++it;
    

    这假定要跳过的字符实际上是一个空格。但是绳子的末端呢?使用以下字符串运行此函数:

    "a test string " // <- space at end

    end() ,循环退出并成功。

    但是,如果没有空间,它将崩溃,因为您已到达终点,正在跳过终点。若要修复,请添加一个检查:

    //skip the space
    if (it != sentence.end())
    {
        ++it;
    }
    

    std::string wordWrap(std::string sentence, int width)
    {    
        std::string::iterator it = sentence.begin();
    
        //remember how long next word is
        int nextWordLength = 0;
        int distanceFromWidth = width;
    
        while (it != sentence.end())
        {
            while (it != sentence.end() && *it != ' ')
            {
                nextWordLength++;
                distanceFromWidth--;
                ++it;
            }
    
            if (it != sentence.end() && nextWordLength > distanceFromWidth)
            {
                *it = '\n';
                distanceFromWidth = width;
                nextWordLength = 0;
            }
    
            //skip the space
            if (it != sentence.end())
            {
                ++it;
            }
    
        }
    
        return sentence;    
    }
    

    您可能会注意到这似乎有很多冗余检查。这可以通过以下方式解决:

    std::string wordWrap(std::string sentence, int width)
    {    
        std::string::iterator it = sentence.begin();
    
        //remember how long next word is
        int nextWordLength = 0;
        int distanceFromWidth = width;
    
        while (it != sentence.end())
        {
            while (*it != ' ')
            {
                nextWordLength++;
                distanceFromWidth--;
    
                ++it;
    
                // check if done
                if (it == sentence.end())
                {
                    return sentence;
                }
            }
    
            if (nextWordLength > distanceFromWidth)
            {
                *it = '\n';
                distanceFromWidth = width;
                nextWordLength = 0;
            }
    
            //skip the space
            ++it;
        }
    
        return sentence;    
    }
    

    希望这有帮助!

        2
  •  5
  •   Adrian Panasiuk    17 年前
    while (*it != ' ' && it != sentence.end())
    

    更改为

    while (it != sentence.end() && *it != ' ')
    

    因此,如果第一个表达式为false,则不计算第二个表达式。

       if (nextWordLength > distanceFromWidth)
    

    应该改成

       if (it == sentence.end())
             break;
       if (nextWordLength > distanceFromWidth)
    
        3
  •  0
  •   csj    17 年前

    *it = '\n';
    

    因为在前面的while循环中,您的停止条件之一是:

    it != sentence.end()
    

    如果它==句子.end(),那么*it='\n'将不会飞行

    还有更多的错误,但正是这些错误导致了您当前的问题。