QByteArray problem



  • Hi guys. I am new in QT. I started developing a programm which working with bytes, and when I tried to use a QbyteArray, I've got some problem. There is a line in QByteArray class reference :
    QByteArray ba;
    ba.resize(5);
    ba[0] = 0x3c;
    ba[1] = 0xb8;
    ba[2] = 0x64;
    ba[3] = 0x18;
    ba[4] = 0xca;
    QByteArray must store 1 byte in each cell of it, but when i trying to do the same it gives me a warning:
    QByteArray ba;
    ba.resize(4);
    ba[0] = 0xFF;
    Result of the output ba[0] is symbol "?". It means that it stored not 8 bit but 6, symbol "?" is 63 in ascii table and 00111111 in binary code. Warning is C4309. How can i store all 8 bits in QByteArray ? (P.S. sorry for my awful English)


  • Qt Champions 2017

    Hi @Zizione:

    QByteArray ba;
    ba.resize(4);
    ba[0] = 0xFF;
    Result of the output ba[0] is symbol "?".

    How did you output it? Your example works perfectly fine for me, I see 0xFF in the debugger.

    It means that it stored not 8 bit but 6, symbol "?" is 63 in ascii table and 00111111 in binary code.

    I rather think, your output cannot display the character for 0xFF and prints a '?' instead.

    Warning is C4309.

    I don't know what the text for this warning is, but I guess it's because QByteArray contains chars and char is signed for most compilers, so it has a range of -128...127. 0xFF is outside this range, hence the warning. You can help yourself with a cast: ba[0] = char(0xFF); or with a literal: ba[0] = '\xFF'

    How can i store all 8 bits in QByteArray ?

    You already do, it's just a matter of output.



  • @aha_1980
    There is my full code , this is just test unit. I need exactly int value in it , and how i understand '\xFF' will store char in it ?

    #include <QCoreApplication>
    #include <QByteArray>
    #include <QString>
    #include <QTextStream>
    int main(int argc, char *argv[])
    {
        QTextStream cin(stdin); cin.setCodec("CP866");
        QTextStream cout(stdout); cout.setCodec("CP866");
        QCoreApplication a(argc, argv);
        QByteArray ba;
        ba.resize(4);
        ba[0] = 0xFF;
        ba[1] = 0xFF;
        ba[2] = 0xF;
        ba[3] = 0xF;
        char tdi[16];
        int b=0;
        for(int i=0;i<4;i++)
        {
            uint16_t mask = 0x8;
            for (int j = 0; j < 4; j++)
            {
                tdi[b] = (ba[i] & mask) ? '1' : '0';
                mask >>= 1;
                b++;
            }
    
        }
        for(int i=0;i<16;i++)
        {
            cout<<tdi[i]<<endl;
        }
        cout<<tdi<<endl;
        cout<<ba[0]<<endl;
        //cout<<sizeof(tdi)<<endl;
        return a.exec();
    }
    


  • welcome to the forum and you are jumping right into a controversial point of the API (see https://forum.qt.io/topic/89766/converting-qbytearray-to-unsigned-char/9). Basically QByteArray interface uses char while you are trying to use unsigned char and hence the warning.

    You can either:

    • ignore the warning (QByteArray is actually storing the correct value it is just casting it to signed)
    • use manual casting: *reinterpret_cast<unsigned char*>(ba.data()[0])=0xFF;
    • use memcpy: const unsigned char tempVal = 0xFF; std::memcpy(ba.data()+0,&tempVal ,1);


  • @VRonin So it is ok with storing 0xFF value , if i need this value in my code from QByteArray it would be given ?



  • Yes, the if you use [] that casts it automatiocally to signed but the value is still 0xff



  • @Zizione
    In addition to the solutions offered by @VRonin....

    I am not a C++-er, but I believe in your case your can use the U suffix to make your constant values unsigned int and thus convertible to unsigned char:

    ba[0] = 0xFFU;
    

    ?



  • @JonB
    Wow, that totally slipped my mind, 👍


  • Qt Champions 2017

    @JonB said in QByteArray problem:

    @Zizione
    In addition to the solutions offered by @VRonin....

    I am not a C++-er, but I believe in your case your can use the U suffix to make your constant values unsigned int and thus convertible to unsigned char:

    ba[0] = 0xFFU;
    

    ?

    Yeah, but ba is signed char...



  • @aha_1980
    true, but the warning one gets with ba[0] = 0xFF is not about usigned and signed char but rather between int and char

    0xFFU == unsigned char(0xFF) == uchar(0xFF) != 0xFF

    the implicit conversation to ba[0] does not "drop" information


  • Qt Champions 2017

    @J.Hilk have you tried?

        QByteArray ba;
        ba.resize(4);
        ba[0] = char(0xFF); // no warning
        ba[1] = 0xFFU; // warning: implicit conversion changes signedness: 'unsigned int' to 'char'
        ba[2] = 0xFF; // warning: implicit conversion changes signedness: 'int' to 'char'
    

    Edit: screenshot



  • @aha_1980 said in QByteArray problem:

    @J.Hilk have you tried?

    I always do, well 95%, before I post ;-)

    0_1523616653797_75eb60ce-4142-42c5-9e3b-9507738d3e70-image.png

    to be honest, I'm surprised about the uint part.


  • Qt Champions 2017

    @J.Hilk

    then you can be surprised about the uchar() part too.

    But the biggest surprise: your code will not even compile in gcc and clang because of line 65.

    And one more hint: your code will crash as you access invalid index in ba ;)



  • @aha_1980 said in QByteArray problem:

    @J.Hilk
    But the biggest surprise: your code will not even compile in gcc and clang because of line 65.

    I saw you using linux in the screen shot and testet that there than, and noticed it too

    And one more hint: your code will crash as you access invalid index in ba ;)

    nope doesn't crash, ignore the project name its my test anything project x).
    0_1523617980226_bd815aeb-ebbc-48dc-8550-62179d940261-image.png !

    resize is apparently not a necessity?

    Edit:
    also ignore value 0, I commeted that line out, to run it with gcc, so theres a random value.
    // ba[0] = unsigned char(0xFF);


  • Qt Champions 2017

    @J.Hilk said in QByteArray problem:

    resize is apparently not a necessity?

    Ah, my fault: "If an assignment is made beyond the end of the byte array, the array is extended with resize() before the assignment takes place."

    A big difference to QVector or QList here.


Log in to reply
 

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