[英]Expression: String iterator not dereferencable
I'm having a hard time using std::string::iterators in C++. 我在C ++中使用std :: string :: iterators遇到困难。 This code compiles fine (still not getting correct output, but that's my fault: TODO, fix algorithm) in Dev-C++, and I don't get runtime errors.
这段代码在Dev-C ++中可以很好地编译(仍然无法获得正确的输出,但这是我的错:TODO,修复算法),而且我没有遇到运行时错误。 The error is with Visual Studio Express 2008 C++, where I'm getting an error pointing to < xstring>: "Expression: string iterator not dereferencable," and points to line 112 of the < xstring> file.
该错误与Visual Studio Express 2008 C ++有关,在这里我得到一个指向<xstring>的错误:“表达式:字符串迭代器不可解除引用”,并指向<xstring>文件的第112行。
My debugging tells me I might be trying to dereference past the end of the sentence input, but I can't see where. 我的调试告诉我,我可能正在尝试在句子输入末尾取消引用,但看不到哪里。 Can anyone shed some light?
谁能阐明一些想法?
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;
}
Firstly, use operator!=() on iterators, not operator<(): 首先,在迭代器上使用operator!=(),而不要在operator <()上使用:
while (it != sentence.end())
Secondly, this is backwards: while (*it != ' ' && it != sentence.end())
其次,这是倒退的:
while (*it != ' ' && it != sentence.end())
You do something with the iterator, than check if the iterator is valid. 您需要对迭代器进行操作,而不是检查迭代器是否有效。 Rather, you should check if it's valid first:
相反,您应该首先检查它是否有效:
while (it != sentence.end() && *it != ' ')
Thirdly, you should use ++iterator over iterator++, though this isn't related to your crashing. 第三,您应该在迭代器上使用++ iterator ++,尽管这与崩溃无关。
Fourth, a main issue is here: 第四,主要问题在这里:
*it = '\n';
Because of the preceeding check, while (it != sentence.end()
, it's possible to reach that iterator dereference while being at the end. A fix would be to do this: 由于前面的检查,
while (it != sentence.end()
,则可能在结束时达到该迭代器的取消引用。解决方法是:
if (it != sentence.end() && nextWordLength > distanceFromWidth)
So now if you have reached the end, you stop. 所以现在,如果您已结束,请停止。
After fixing the previous issue, now the only problem is this: 解决了上一个问题之后,现在唯一的问题是:
//skip the space
++it;
This assumes that the character you are skipping is in fact a space. 这假定您要跳过的字符实际上是一个空格。 But what about the end of the string?
但是字符串的结尾呢? Run this function with this string:
使用以下字符串运行此函数:
"a test string " // <- space at end
And it will succeed; 它会成功; it skips the space, putting the iterator at
end()
, the loop exits and success. 它跳过空间,将迭代器放在
end()
,循环退出并成功。
However, without the space it will crash, because you have reached the end, and are skipping past the end. 但是,如果没有空间,它将崩溃,因为您已经到达终点,并且正在跳过终点。 To fix, add a check:
要修复,请添加检查:
//skip the space
if (it != sentence.end())
{
++it;
}
Resulting in this final code: 最终代码如下:
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;
}
You might notice this seems like it has a lot of redundant checks. 您可能会注意到,这似乎有很多多余的检查。 This can be fixed:
这可以解决:
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;
}
Hopefully that helps! 希望有帮助!
while (*it != ' ' && it != sentence.end())
changes to 更改为
while (it != sentence.end() && *it != ' ')
so the second expression isn't evaluated if the first if false. 因此,如果第一个表达式为false,则不会计算第二个表达式。
if (nextWordLength > distanceFromWidth)
should probably change to 应该更改为
if (it == sentence.end())
break;
if (nextWordLength > distanceFromWidth)
Almost certainly your error is the result of: 几乎可以肯定,您的错误是由于以下原因造成的:
*it = '\n';
Since in the preceding while loop one of your stopping conditions is: 由于在前面的while循环中,您的停止条件之一是:
it != sentence.end()
If it == sentence.end(), then *it = '\\n' won't fly 如果它==句子.end(),则* it ='\\ n'不会飞
There are more errors, but that's the one that's causing your current problem. 还有更多错误,但这是导致当前问题的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.