質問

私はC ++でのstd ::文字列::イテレータを使用して苦労しています。このコードは(まだ正しい出力を得ていないが、それは私のせいです:TODOは、アルゴリズムを修正する)微コンパイルのDev-C ++で、と私はランタイムエラーを得ることはありません。エラーは、私がを指してエラーを取得していますのVisual Studio Expressの2008 C ++である:「式:文字列イテレータdereferencableない」との点は、ファイルの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;    
}
役に立ちましたか?

解決

まず、使用演算子=()イテレータではなく、演算子<():

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

うまくいけば、それは役立ちます!

他のヒント

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

に変更

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

falseの場合最初。場合に、第2の式が評価されていないので

   if (nextWordLength > distanceFromWidth)

おそらくに変更する必要があります。

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

ほぼ確実にあなたのエラーは結果があります:

*it = '\n';

であるため、先行するあなたの停止条件のループ1であるのに対します:

it != sentence.end()

もしそれ== sentence.end()、そして*それ= '\ nは' 飛ばないだろう。

があり複数のエラーがありますが、それはあなたの現在の問題を引き起こしている一つだ。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top