[SOLVED] String to double conversion failed and issues with qDebug



  • I'm receiving data from usb and i convert them to QString. Then the message is separated
    to different variable. In the end i want these variables to double type but using the qDebug
    my output is 0 "4, so 0 is for lat which means the conversion failed and "4 is for latitude
    but why only the first character? The string is many bytes long.

    @std::string message(usb_data.constData(), 60); //usb_data.length()
    QString qmessage = QString::fromStdString(message);
    QString latitude = qmessage.mid(0,21);
    QString longitude = qmessage.mid(23,25);
    QString height = qmessage.mid(50);

        QString lat_mid = qmessage.mid(0,18);
        QString lon_mid = qmessage.mid(23,21);
    
    
    
    
        double lat =  lat_mid.toDouble();
        double lon =  lon_mid.toDouble();
    
        qDebug() << lat << latitude;@

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Can you show the content of latitude, longitude, lat_mid and lon_mid ?



  • hey nice to be here,
    latitude contains something like 40.705465,E
    longitude -74.026566,S
    lat_mid 40.705465
    lon_mid -74.026566

    So i am removing the ,E and ,S to be able to convert to double but i get 0.
    There might be non-printable characters messing with the conversion.



  • This line of code @qDebug() << lat_mid.toLatin1();@

    outputs to this "4

    this line of code @qDebug() << lat_mid.toLatin1().toHex();@

    outputs to this "34003000340035002e003800390032003100"

    I had a look at the "ascii chart":http://en.wikipedia.org/wiki/ASCII#ASCII_control_characters and apparently every
    00 is misinterpreted to a null character.



  • What is a result of std::cout instead of qDebug()
    What is a result of using QByteArray as intermediate variable ?
    @
    QByteArray data = lat_mid.toLatin1();
    qDebug() << data;
    qDebug() << data.data();
    @



  • [quote author="andreyc" date="1409010147"]What is a result of std::cout instead of qDebug()[/quote]

    Don't know how to make this work. Even @std::cout << "asdf" << endl;@
    doesn't show up anywhere. But it built.

    [quote author="andreyc" date="1409010147"]What is a result of using QByteArray as intermediate variable ?
    @
    QByteArray data = lat_mid.toLatin1();
    qDebug() << data;
    qDebug() << data.data();
    @
    [/quote]

    The result is "4 for the first and 4 for the second



  • What about
    @
    QByteArray data = lat_mid.toLocal8Bit();
    @



  • Scratch my previous suggestions.
    I think you need to write your own deserializer.

    Something simple like skipping each other byte in a for loop.
    Or using QByteArray and QDataStream
    @
    class MyData
    {
    ...
    QString toString() const;
    };
    QDataStream &operator>>(QDataStream &in, MyData &data);

    QByteArray data = QByteArray::fromRawData(usb_data.constData(), 60);
    QDataStream in(&data, QIODevice::ReadOnly);
    MyData data;
    in >> data;
    qDebug() << data.toString();
    @



  • And one more attempt.

    I guess that usb_data.constData() returns const char*
    @
    QString qmessage = QString::fromUtf16(reinterpret_cast<const unsigned short*>(usb_data.constData()));
    @

    [EDIT] Example
    @
    const char* latStr = "\x34\x00\x30\x00\x34\x00\x35\x00\x2e\x00\x38\x00\x39\x00\x32\x00\x31\x00";
    QString str1 = QString::fromUtf16(reinterpret_cast<const unsigned short*>(latStr));
    qDebug() << str1;
    @
    output
    @
    "4045.8921"
    @


  • Lifetime Qt Champion

    By the way, what class is usb_data ?



  • [quote author="andreyc" date="1409012176"]What about
    @
    QByteArray data = lat_mid.toLocal8Bit();
    @[/quote]

    Still the same "4 and 4. I'll have a look at your other suggestion.

    [quote author="SGaist" date="1409038961"]By the way, what class is usb_data ?[/quote]

    It's Qbytearray.



  • [quote author="andreyc" date="1409020154"]And one more attempt.

    I guess that usb_data.constData() returns const char*
    @
    QString qmessage = QString::fromUtf16(reinterpret_cast<const unsigned short*>(usb_data.constData()));
    @

    [EDIT] Example
    @
    const char* latStr = "\x34\x00\x30\x00\x34\x00\x35\x00\x2e\x00\x38\x00\x39\x00\x32\x00\x31\x00";
    QString str1 = QString::fromUtf16(reinterpret_cast<const unsigned short*>(latStr));
    qDebug() << str1;
    @
    output

    "4045.8921"

    [/quote]

    I used your example @QString str1 = QString::fromUtf16(reinterpret_cast<const unsigned short*>(lat_mid));
    qDebug() << str1;@

    but i get an error @error C2440: 'reinterpret_cast' : cannot convert from 'QString' to 'const unsigned short *'@



  • Also this is how usb_data is created @QByteArray usb_data(reinterpret_cast<char*>(buf), sizeof(buf));@



  • [quote author="QG90" date="1409047489"]
    I used your example
    @
    QString str1 = QString::fromUtf16(reinterpret_cast<const unsigned short*>(lat_mid));
    qDebug() << str1;
    @
    but i get an error
    @
    error C2440: 'reinterpret_cast' : cannot convert from 'QString' to 'const unsigned short *'
    @
    [/quote]

    It want work. If I understand it correctly you are getting UTF16 string from USB. UTF16 contains zeros, not number 0 but ascii code 0. And it will break any standard string operations.
    So, if you prefer to use standard string operations (QString etc) you need to translate you incoming buffer to a regular string.

    [quote author="QG90" date="1409054635"]
    Also this is how usb_data is created @QByteArray usb_data(reinterpret_cast<char*>(buf), sizeof(buf));@
    [/quote]

    Instead of converting buf to QByteArray convert it to QString
    @
    QString usbStr;
    usbStr = QString::fromUtf16(reinterpret_cast<const unsigned short*>(buf), sizeof(buf));
    @

    And then
    @
    QString latitude = usbStr.mid(0,21);
    QString longitude = usbStr.mid(23,25);
    QString height = usbStr.mid(50);

    QString lat_mid = usbStr.mid(0,18);
    QString lon_mid = usbStr.mid(23,21);

    double lat = lat_mid.toDouble();
    double lon = lon_mid.toDouble();

    qDebug() << lat << latitude;
    @



  • It seems to work!!!! Now on qDebug i receive 4045.88 "4045.8783,N"
    probably the 783 part on the number sums to an 8.



  • Yep, looks like legitimate rounding.
    I think qDebug() does rounding because I don't see any rounding rules in QString::toDouble().

    If you consider this thread as solved then please add [SOLVED] to the title of your original post.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.