簡體   English   中英

表達式:不可迭代的字符串迭代器

[英]Expression: String iterator not dereferencable

我在C ++中使用std :: string :: iterators遇到困難。 這段代碼在Dev-C ++中可以很好地編譯(仍然無法獲得正確的輸出,但這是我的錯:TODO,修復算法),而且我沒有遇到運行時錯誤。 該錯誤與Visual Studio Express 2008 C ++有關,在這里我得到一個指向<xstring>的錯誤:“表達式:字符串迭代器不可解除引用”,並指向<xstring>文件的第112行。

我的調試告訴我,我可能正在嘗試在句子輸入末尾取消引用,但看不到哪里。 誰能闡明一些想法?

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

首先,在迭代器上使用operator!=(),而不要在operator <()上使用:

while (it != sentence.end())

其次,這是倒退的: while (*it != ' ' && it != sentence.end())

您需要對迭代器進行操作,而不是檢查迭代器是否有效。 相反,您應該首先檢查它是否有效:

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

第三,您應該在迭代器上使用++ iterator ++,盡管這與崩潰無關。


第四,主要問題在這里:

*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;    
}

希望有幫助!

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

更改為

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

因此,如果第一個表達式為false,則不會計算第二個表達式。

   if (nextWordLength > distanceFromWidth)

應該更改為

   if (it == sentence.end())
         break;
   if (nextWordLength > distanceFromWidth)

幾乎可以肯定,您的錯誤是由於以下原因造成的:

*it = '\n';

由於在前面的while循環中,您的停止條件之一是:

it != sentence.end()

如果它==句子.end(),則* it ='\\ n'不會飛

還有更多錯誤,但這是導致當前問題的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM