具有2个小数位的浮点值会导致无限循环

时间:2016-07-18 19:43:46

标签: c++ qt infinite-loop

我正在尝试编写一个在html字符串中更改font-size的方法。当我点击“减号”按钮时,我将当前大小乘以0.8,当我点击“加号”按钮时,我将当前大小乘以1.25! 问题出在htmlStyle.replace(pos, length, newString);行,'newString'参数。我想通了,如果我传递一个包含字符串格式的数字的字符串,例如1.2,那就没问题。但是,如果我以字符串格式传递一个数字,该数字乘以1.22或1.34或带有两个小数位的任何浮点数,它会导致无限循环并且应用程序崩溃。 我真的没有得到这里的问题,因为这些是字符串,并且在成功计算'newString'之后出现问题。 有任何想法吗?我试图弄清楚这两天,但我还是一无所知......

这是完整的方法:

QString RichTextSize::setSizes(QString htmlStyle, float multiplier)
{
    QRegExp rx("(\\d+)pt");
    int pos = 0, length = 0;
    QString newString;

    while ((pos = rx.indexIn(htmlStyle, pos)) != -1) {
        length = rx.cap(1).length();
        newString.setNum(rx.cap(1).toInt()*multiplier);
        htmlStyle.replace(pos, length, newString);
        pos += rx.matchedLength();
    }
    return htmlStyle;
}
编辑:我收到了关于可能重复的问题的通知。好吧,我的问题不是浮点数学,但它是以某种方式浮动的。浮点运算没有问题。当麻烦发生时,将浮点数转换为字符串。它成功转换,但在'replace()'方法中它会导致无限循环。它以某种方式被浮点小数点所取代,但由于该操作有效并且问题是从该数字转换的字符串,我不明白这里发生了什么。

1 个答案:

答案 0 :(得分:2)

您正在使用pos作为字符串的迭代器,但通过修改字符串,您将使迭代器无效。循环不保证再次终止。而且,正如你已经发现的那样,它没有。

您所做的无效假设可以明确:

while ((pos = rx.indexIn(htmlStyle, pos)) != -1) {
    length = rx.cap(1).length();
    newString.setNum(rx.cap(1).toInt()*multiplier);
    htmlStyle.replace(pos, length, newString);
    Q_ASSERT(rx.matchedLength() == newString.size());
    pos += rx.matchedLength();
}

一旦该断言不成立,循环可能不再终止,或者您可能正在访问超过其长度的字符串等。

理想情况下,您应该迭代常量字符串,以便迭代器保持有效,并构建新的输出字符串。这也会更快。

另一种方法是修复迭代器更新,使其不会失效。提示:pos += rx.matchedLength()基于字符串的无效部分:它在htmlStyle.replace之前是正确的,但现在不再存在。也许你的意思是pos += newString.size()