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

Reading char array from QDataStream



  • I have a binary file from an old game Fallout 2 which contains these items (simplified):

    unsigned int textSize = 3;
    char[textSize] text = "abc";
    // next item
    unsigned int textSize = 6;
    char[textSize] text = "abcdef";
    // and so on
    

    Currently, I read the values like this:

        QFile file("master.dat");
        file.open(QIODevice::ReadOnly);
    
        QDataStream stream(&file);
        stream.setByteOrder(QDataStream::LittleEndian);
    
        for(qint32 i = 0; i < number_of_items; ++i)
        {
            qint32 length;
            QString text;
    
            stream >> length;
    
            for(int j = 0; j < length; ++j)
            {
                qint8 character;
                stream >> character;
                text.append(character);
            }
            qDebug() << "Text    = " << text;
        }
        file.flush();
        file.close();
    

    It works fine, but it feels like I am not doing it the right way. I also tried doing this:

    qint32 length;
    stream >> length;
    char *text = new char[length]
    stream.readRawData(text, length);
    qDebug() << text;
    delete[] text;
    

    but when I do it like this, the text I get has some garbage at the end. For example, instead of "NAR_VC5.ACM" I get "NAR_VC5.ACMMd\u0006" which looks like I am not allocating the correct size for the string or it is missing the terminating character \0?

    What is the correct way of using QDataStream for this purpose?



  • I will not go in the details of a reverse-engineered file format and just answer your question (here I'm assuming text is encoded using utf-8):

    qint32 length;
    QByteArray rawText;
    QString text;
    stream >> length;
    rawText.resize(length);
    if(stream.readRawData(rawText.data(),length)==length){
    text = QString::fromUtf8(rawText);
    }
    
    

  • Lifetime Qt Champion

    @Jansi

    well, you will need to make your buffers larger and NULL-terminate them youself.

    Example: char x[] = "abc"; will be NULL-terminated and the same as char y[4] = "abc";, while char z[3] = "abc"; will not be terminated as the buffer is to small.

    regards


Log in to reply