2009-06-30 10 views
0

C++でstd :: string :: iteratorsを使用するのに苦労しています。このコードは、(正しい出力を得ることはできませんが、それでも私の誤りです:TODO、アルゴリズムを修正してください)Dev-C++でコンパイルしても、ランタイムエラーは発生しません。エラーは、Visual Studio Express 2008 C++で、< xstring>: "式:文字列反復子が逆参照できません"を指すエラーが発生し、< xstring>ファイルの112行目を指しています。式:文字列イテレータを逆参照できない

私のデバッグでは、私は文入力の最後を逆参照しようとしている可能性があると言いますが、私はどこに見えません。誰か光を当てることはできますか?最初の場合はfalseの場合はそう二式が評価されていない

while (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 != ' ' && it != sentence.end()) 
     { 
      nextWordLength++; 
      distanceFromWidth--; 
      it++; 
     } 

     if (nextWordLength > distanceFromWidth) 
     { 
      *it = '\n'; 
      distanceFromWidth = width; 
      nextWordLength = 0; 
     } 

     //skip the space 
     it++; 

    } 

    return sentence;  
} 

答えて

15

に変更する必要があります:while (*it != ' ' && it != sentence.end())

イテレータが有効かどうかを確認するよりも、イテレータを使用して何かを行うことができます。むしろ、あなたはそれが最初の有効なのですかどうかを確認する必要がありますこれはあなたのクラッシュに関連していないものの

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

第三に、あなたは、++イテレータを超える++イテレータを使用する必要があります。


第四には、主な問題はここにある:ので先行チェック、while (it != sentence.end()

*it = '\n'; 

、それは終わりでありながらそのイテレータデリファレンスに到達することが可能です。この問題を解決するには、次のようにします。

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

うまくいけば役立ちます!

+0

+1。私はポイント2のコードを完全なコードブロックと説明と一致させるように修正しました。 –

+0

ありがとうございます。私はそれを知っているので(コンパイラは余分なイテレータをコピーすることを知っています)、!=を使用しています。 !=でコンパイルするときにエラーが発生していました。文字列が連続していることがわかって以来、私は休憩を取っていました。私はスタックのようなものでは同じことをしません。質問:あなたのコードでは、ループ外に出たら例外をスローする方が良いでしょうか?あなたのソリューションでは、あなたはただ戻ります。それはいくつかの重大な問題を隠すことができるようです。 – jkeys

+0

私はループ外で何を意味するのか分かりません。上記のコードは安全であり、例外をスローする必要はありません。 – GManNickG

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

変更。 !

while (it != sentence.end()) 

第二に、これは逆方向である:

if (nextWordLength > distanceFromWidth) 

はおそらく、イテレータの使用演算子=()、not演算子<()は、

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

ほぼ確実にあなたのエラーは結果である:あなたの停止条件のループ1であるのに対し、先行しているので

*it = '\n'; 

it != sentence.end() 

それはsentence.endを(==場合)、 * '=' \ n 'は飛べません。

これ以上のエラーはありますが、それがあなたの現在の問題を引き起こしています。

関連する問題