Question

There is an issue using QString::arg() when a string contains a digit right after a place marker. It's not clear from the QString::arg() function description what would happen in case of such a replacement:

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

Will this result in "String for replacement blah234" or "String for replacement blah34"?

I looked in the QT's source code to answer this question. It seems that the algorithm which looks for place markers is 'greedy' and it would take both digits in the example above.

Here is the source of the QT's function which is used inside the QString::arg() (QT 4.8.4):

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

Is there a better way of solving such an ambiguity than always using a 2-digit place markers?

Was it helpful?

Solution

Since you can only use %1 to %99 as markers and you can skip marker numbers you can write:

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

to output String for replacement blah234

OTHER TIPS

Qt help states for arg(const QString & a, int fieldWidth = 0, QChar fillChar = QLatin1Char( ' ' ))

Returns a copy of this string with the lowest numbered place marker replaced by string a, i.e., %1, %2, ..., %99.

...

Place marker numbers must be in the range 1 to 99.

Therefore, what you're seeing is, by definition, correct; the first two numbers will be replaced. If you're wanting "String for replacement blah234", then you could define the string as: -

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

I have the same issue, but the order answers not looks like a good way for me.

I have resolve the ambiguity in this way.

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

The string will be:

ConcatenatedNumbers06623
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top