まず、operator<() ではなく、イテレータで operator!=() を使用します。
while (it != sentence.end())
第二に、これは逆です:while (*it != ' ' && it != sentence.end())
イテレータが有効かどうかを確認するよりも、イテレータで何かをします。むしろ、最初に有効かどうかを確認する必要があります。
while (it != sentence.end() && *it != ' ')
第三に、これはクラッシュとは関係ありませんが、iterator++ よりも ++iterator を使用する必要があります。
第 4 に、主な問題は次のとおりです。
*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;
}
うまくいけば、それは役に立ちます!