表达式:字符串迭代器不可取消引用

发布于 2024-07-25 08:18:38 字数 984 浏览 10 评论 0原文

我在 C++ 中使用 std::string::iterators 遇到了困难。 这段代码在 Dev-C++ 中编译得很好(仍然没有得到正确的输出,但这是我的错:TODO,修复算法),并且我没有收到运行时错误。 该错误出现在 Visual Studio Express 2008 C++ 中,我收到一个指向 << 的错误。 xstring>:“表达式:字符串迭代器不可取消引用”,并指向的第 112 行。 x字符串> 文件。

我的调试告诉我,我可能试图取消引用超过句子输入的末尾,但我看不到在哪里。 任何人都可以透露一些信息吗?

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

I'm having a hard time using std::string::iterators in C++. 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. 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.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

心安伴我暖 2024-08-01 08:18:38

首先,在迭代器上使用operator!=(),而不是operator<():

while (it != sentence.end())

其次,这是向后的:while (*it != ' ' && it !=句子.end())

您对迭代器执行一些操作,而不是检查迭代器是否有效。 相反,您应该首先检查它是否有效:

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

第三,您应该使用 ++iterator 而不是 iterator++,尽管这与您的崩溃无关。


第四,这里有一个主要问题:

*it = '\n';

由于前面的检查,while (it != moment.end()),有可能在末尾达到迭代器取消引用。解决方法是这样做:

if (it != sentence.end() && nextWordLength > distanceFromWidth)

所以现在如果你已经到达末尾,那么


在解决了上一个问题之后,现在唯一的问题是:

//skip the space
++it;

这假设你要跳过的字符实际上是一个空格,但是字符串的末尾呢?使用以下字符串运行此函数:

"a test string " // <- space at end

它会成功跳过空格,将迭代器放在 end() code>,循环退出并成功。

但是,如果没有空格,它会崩溃,因为您已经到达末尾,并且要跳过末尾,要修复此问题,请添加一个检查:

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

希望这有帮助!

Firstly, use operator!=() on iterators, not operator<():

while (it != sentence.end())

Secondly, this is backwards: 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.


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:

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.

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!

与他有关 2024-08-01 08:18:38
while (*it != ' ' && it != sentence.end())

更改为

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

,因此如果第一个表达式为 false,则不会计算第二个表达式。

   if (nextWordLength > distanceFromWidth)

可能应该改为

   if (it == sentence.end())
         break;
   if (nextWordLength > distanceFromWidth)
while (*it != ' ' && it != sentence.end())

changes to

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

so the second expression isn't evaluated if the first if false.

   if (nextWordLength > distanceFromWidth)

should probably change to

   if (it == sentence.end())
         break;
   if (nextWordLength > distanceFromWidth)
此刻的回忆 2024-08-01 08:18:38

几乎可以肯定你的错误是由以下原因造成的:

*it = '\n';

因为在前面的 while 循环中,你的停止条件之一是:

it != sentence.end()

If it == sense.end(), then *it = '\n' won't Fly

还有更多错误,但是这就是导致您当前问题的原因。

Almost certainly your error is the result of:

*it = '\n';

Since in the preceding while loop one of your stopping conditions is:

it != sentence.end()

If it == sentence.end(), then *it = '\n' won't fly

There are more errors, but that's the one that's causing your current problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文