Please nominate your Qt Champions for 2021!

Problem with QString and it arg()

  • If I reorder my "%"-placeholders, QString with arg can't process them correctly.
    I can't find any documentation on what I am doing wrong. This happens on Qt 4.8.5 and Qt 5.2
    Code below demonstrates the issue:
    Test 4 fails.. it fails to replace a placeholder..

    @ void UnitTests::test_stringArgs()
    QString expected = QString("Area52");
    QString test1 = QString("%1%2%3").arg("Area").arg(5).arg(2);
    QString test2 = QString("%1%3_%2_").arg("Area").arg(2).arg(5);
    QString test3 = QString("%1%3%2").arg("Area").arg(2);
    QString test4 = QString("%1%3%2").arg("Area").arg(2).arg(5);

        QCOMPARE(expected, test1);
        QCOMPARE(QString("_Area_5_2_"), test2);
        // code block remove my %3, hence the " ' " after it 
        QCOMPARE(QString("_Area%3'2_"), test3);  
        QCOMPARE(expected, test4);
    FAIL!  on line 13: test_stringArgs() Compared values are not the same
      Actual (expected): _Area52_
      Expected (test4): _Area5_@

    Is this a QString bug?

  • Hi, dunno how this works exactly but could the problem be in the order?

    u have:
    QString test4 = QString("%1%3%2").arg("Area").arg(2).arg(5);
    it should be:
    QString test4 = QString("%1%3%2").arg("Area").arg(5).arg(2);

  • Swapping the arguments is done on purpose..
    Notice that %3 is place in front of %2

    Constructing a "%1%2%3" string works fine
    Constructing a "%1%3%2" fails.. %2 gets lost somehow?

    [quote author="roseicollis" date="1421756070"]Hi, dunno how this works exactly but could the problem be in the order?

    u have:
    QString test4 = QString("%1%3%2").arg("Area").arg(2).arg(5);
    it should be:
    QString test4 = QString("%1%3%2").arg("Area").arg(5).arg(2);[/quote]

  • I can confirm that on Windows Qt 4.8.6 VS 2010 I see the following behavior:
    QString test4 = QString("%1%3%2").arg("Area").arg(20).arg(50);
    QString test4m = QString("%1%2%3").arg("Area").arg(50).arg(20);
    Q_ASSERT (test4 == test4m);

    Assert fails due to:

    • test4 "Area500" QString
    • test4m "Area5020" QString
      It looks like first digit of the %2 is skipped
      I suggest to report bug.
      It is funny bug was not found yet.


  • Hi, I see the bug also on my Mac with Qt 5.4: if the first character in %2 is a digit 0-9 it gets eaten. Good find!

  • I to can confirm this on Qt 5.4.x on Win 8.1 using MSVC2013 32 bit:


  • Seems to be wanted behavior.....

    The %1%3%2 with arg("Area") becomes Area%3%2
    Area%3%2 with arg(20) becomes Area%3 20
    Now note how the documentation says that it will replace % up to 99, so...
    Area%3 20 with arg(50) becomes Area500 as it will only replace 2, not %3

    Although I think this is unwanted behavior for most of the people using the qt library. We heavily use placeholders for translations and thus don't control the arg input. I don't want arg to dynamicly change my placeholders..

  • Aha, thanks for posting this, I've seen in the docs for QString that there's actually 2 ways you can use the arg() function:

    string.arg(1).arg(2).arg(3);     or

    and the docs says that the difference is that the 2nd version "replaces the arguments in one pass". Until know I didn't really pay attention to what that meant. So this implies that the 1st version iterates the replacements, so indeed this is wanted (designed) behavior.
    But it sure looked like a bug :-)

  • I would say it seems reasonable if you count that arg is just a function,
    Qt documentation should have warning about usage of the string.arg(1).arg(2).arg(3); pattern

    I just hope that in my Qt career I have not introduced such disaster. The only hope is that my strings always had some kind of additional separators.

  • Lifetime Qt Champion

    Documentation improvement is on its way

Log in to reply