我很难在C ++中使用std :: string :: iterators。这段代码编译很好(仍然没有得到正确的输出,但这是我的错:TODO,修复算法)在Dev-C ++中,我没有得到运行时错误。错误是使用Visual Studio Express 2008 C ++,我收到错误指向< xstring>:“Expression:string iterator not dereferencable”,并指向< 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;
}
答案 0 :(得分:15)
首先,在迭代器上使用operator!=(),而不是运算符&lt;():
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;
}
希望这有帮助!
答案 1 :(得分:5)
while (*it != ' ' && it != sentence.end())
更改为
while (it != sentence.end() && *it != ' ')
所以如果第一个表达式为false,则不评估第二个表达式。
if (nextWordLength > distanceFromWidth)
应该改为
if (it == sentence.end())
break;
if (nextWordLength > distanceFromWidth)
答案 2 :(得分:0)
几乎可以肯定你的错误是由于:
*it = '\n';
因为在前面的while循环中,你的一个停止条件是:
it != sentence.end()
如果它== sentence.end(),则* it ='\ n'将不会飞
还有更多错误,但这是导致您当前问题的错误。