Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QString::sprintf question



  • Hi, I have a silly question regarding QString::sprintf. It is not a static function, so I need to call it on an instance of QString, but this instance does not appear to be used at all, causing me to have to create dummy variables all the time, like this:
    @
    QString stringFromQVector3D(const QVector3D &vector)
    {
    QString dummy;

    return dummy.sprintf("%.3f, %.3f, %.3f", vector.x(), vector.y(), vector.z());
    

    }@

    This works perfectly, but it doesn't seem very elegant. I'm wondering if I'm misunderstanding something.

    I should mention that I prefer the sprintf style formatting as this is way easier for me to read and edit than glueing pieces of strings together.



  • Have a look at the arg function of QString. If you ever need translations it's your best choice

    From the docs :

    @ QString i; // current file's number
    QString total; // number of files to process
    QString fileName; // current file's name

     QString status = QString("Processing file %1 of %2: %3")
                     .arg(i).arg(total).arg(fileName);@
    


  • I guess you have seen the warning in "sprintf description":http://doc.qt.nokia.com/4.7/qstring.html#sprintf Because of that I would twice before using sprintf. Therefore, I could only repeat Eddy's advice.



  • bq. I guess you have seen the warning in sprintf description [doc.qt.nokia.com] Because of that I would twice before using sprintf. Therefore, I could only repeat Eddy’s advice.

    Thanks, I would use something else if there was another "safe" function with sprintf style formatting. Doesn't arg() only work with strings?



  • Afaik arg is only used with QString

    Edit : i didn't mean as argument, because it has several overloaded variants. I meant it's a function that you can find in the QString class only.



  • You got a whole of overlaid methods. Just take your pick.
    This is for "int for example ":http://doc.qt.nokia.com/4.7/qstring.html#arg-10



  • [quote author="Eddy" date="1309451732"]Afaik arg is only used with QString[/quote]

    It writes only to strings, but the actual argument may be different.

    There was an overlap of our replies. :-)



  • Ah, I saw all the overloads now for all the other types.

    arg() could be the next best thing :) Thanks a lot!



  • [quote author="koahnig" date="1309451893"]
    [quote author="Eddy" date="1309451732"]Afaik arg is only used with QString[/quote]

    It writes only to strings, but the actual argument may be different.

    There was an overlap of our replies. :-)
    [/quote]

    Yes i was just editing my post because i tought eonz could have not seen all the overloaded functions



  • @Eddy:
    To answer your ? as asked, without trying to sell someone on the Qt way of doing arguments:

    return QString().asprintf("%.3f, %.3f, %.3f", vector.x(), vector.y(), vector.z());

    Note that the Qt arguments version lacks the three decimal points specifications given in the original question. Note also that while three decimal points can be done in the Qt arguments way of doing it, there is no single table that pulls together all the args() specifications conveniently, like a printf table does. The .args() way of doing it isn't always more convenient.

    Note that this doesn't limit the size of the result; and can result in buffer overflows, if you e.g. are printing a string with %s or %ls. While it is argued that you should use .arg() because it supports Unicode unlike QString::asprintf(), this is untrue. The documentation says that if your format specifier is %ls, it will print a Unicode string. The documentation claims that asprintf() will safely build a string, but that sprintf() is obsolete - although I am unclear on any real difference.

    The argument has been made that snprintf should not be used, since different compilers and locales may cause differing lengths of strings; but I'd say it is more important not to overflow buffers, or even use huge, unintended chunks of memory with a %s specifier, than it is to get every character in.

    You can use Unicode in such a context. Here's a £337 way of doing it:

    wchar_t buf[100];
    std::swprintf(buf, 100, L"%.3f, %.3f, %.3f, %s", vector.x(), vector.y(), vector.z(), someWCharString);
    return QString().fromWCharArray(buf);


  • Moderators

    @Morbius Both asprintf and fromWCharArray are static methods. Don't create temporary instances just to call them. Just use directly: QString::asprintf(... and QString::fromWCharArray(...

    You don't need std to use Unicode (and by Unicode I mean UTF-16, just to be clear, because there's more then one type of Unicode).
    QString is UTF-16 internally so there's no point in doing it via std::swprintf. Format string in QString::asprintf is expected to be UTF-8 so it can hold whatever UTF-16 can. If you have arguments that are UTF-16 strings then these are also supported directly via %lc and %ls.


Log in to reply