【问题标题】:Solving QT's QString arg() ambiguity解决 QT 的 QString arg() 歧义
【发布时间】:2013-05-20 04:25:29
【问题描述】:

当字符串在位置标记之后包含一个数字时,使用QString::arg() 会出现问题。从QString::arg() 函数描述中不清楚在这种替换的情况下会发生什么:

QString("String for replacement %1234").arg("blah");

这会导致"String for replacement blah234""String for replacement blah34"

我查看了 QT 的源代码来回答这个问题。似乎寻找地点标记的算法是“贪婪”的,并且在上面的示例中它会占用两个数字。

这是在QString::arg() (QT 4.8.4) 中使用的 QT 函数的来源:

static ArgEscapeData findArgEscapes(const QString &s)
{
const QChar *uc_begin = s.unicode();
const QChar *uc_end = uc_begin + s.length();

ArgEscapeData d;

d.min_escape = INT_MAX;
d.occurrences = 0;
d.escape_len = 0;
d.locale_occurrences = 0;

const QChar *c = uc_begin;
while (c != uc_end) {
    while (c != uc_end && c->unicode() != '%')
        ++c;

    if (c == uc_end)
        break;
    const QChar *escape_start = c;
    if (++c == uc_end)
        break;

    bool locale_arg = false;
    if (c->unicode() == 'L') {
        locale_arg = true;
        if (++c == uc_end)
            break;
    }

    if (c->digitValue() == -1)
        continue;

    int escape = c->digitValue();
    ++c;

    if (c != uc_end && c->digitValue() != -1) {
        escape = (10 * escape) + c->digitValue();
        ++c;
    }

    if (escape > d.min_escape)
        continue;

    if (escape < d.min_escape) {
        d.min_escape = escape;
        d.occurrences = 0;
        d.escape_len = 0;
        d.locale_occurrences = 0;
    }

    ++d.occurrences;
    if (locale_arg)
        ++d.locale_occurrences;
    d.escape_len += c - escape_start;
}
return d;
}

有没有比总是使用 2 位数字位置标记更好的方法来解决这种歧义?

【问题讨论】:

  • 这是一个很好的观察,我从来没有想过这个。我唯一想做的就是QString("String for replacement %1%2").arg("blah").arg(234);,但这太丑了。

标签: qt qstring ambiguity


【解决方案1】:

arg(const QString & a, int fieldWidth = 0, QChar fillChar = QLatin1Char( ' ' )) 的 Qt 帮助状态

返回此字符串的副本,其中编号最小的位置标记替换为字符串 a,即 %1、%2、...、%99。

...

地点标记编号必须在 1 到 99 之间。

因此,根据定义,您所看到的是正确的;前两个数字将被替换。如果您想要“替换 blah234 的字符串”,那么您可以将字符串定义为:-

QString("String for replacement %1%2").arg("blah").arg(234);

【讨论】:

  • 我并不是说有什么不正确的。我是说位置标记后的数字会产生一些歧义。在您的解决方案中,位置标记之间有额外的空间。如果有空格,则不存在这样的问题。
【解决方案2】:

由于您只能使用%1%99 作为标记,并且可以跳过标记编号,因此可以编写:

QString("String for replacement %10234").arg("blah");

输出字符串替换blah234

【讨论】:

  • 并评论它,因为这对于下一个查看代码的人(或者从现在起 3 年后的你自己)肯定不会直观。至少它可以工作。
【解决方案3】:

我有同样的问题,但订单答案对我来说不是一个好方法。

我已经通过这种方式解决了歧义。

QString myString= QString("ConcatenatedNumbers%0123").arg(66,3,10, QChar('0'));

字符串将是:

ConcatenatedNumbers06623

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多