0

Qt API を使用して unsigned short の配列を読み込もうとしています。残念ながら、私は望ましい結果を得ていません。

次のコード

        QFile in(fileName);
        int len = in.size();
        QDataStream d(&in);

        quint16 *data = new quint16[len];
        qDebug() << data[0];
        qDebug() << data[1];
        d >> data[0];
        qDebug() << data[0];
        qDebug() << data[1];

出力

         52685 
         52685 
         13109 
         52685 

データが最初の配列位置でのみ変更されることを意味します。また、配列はゼロ初期化されているといつも思っていましたか? ここではa を使用してQByteArrayもうまくいかないようです。そのため、quint16(= unsigned shorts) の配列を使用しようとしています。ループを使用することもできますが、可能な限りコストのかかるループを回避しようとしています。

では、どのようにして上記の配列 (データ) にファイルからの目的のデータを入力するのでしょうか? を使用してデータを運ぶことは可能QByteArrayですか?

4

2 に答える 2

3

まずin.size()、ファイルのサイズをバイト単位で返します。 unsigned short (それぞれ 2 バイト) を使用しているため、データ配列のサイズはlen/2.

また、シリアル化のために QDataStream が提供されています。これは、一度に 1 つのオブジェクトを抽出する場合に主に役立つことを意味します。詳細については、QDataStrean のドキュメントを参照してください。

次のコードを使用すると、ループやコピーを行わずに配列全体を抽出できます。

QFile in(fileName);
in.open(QFile::ReadOnly);
QByteArray byteArray = in.readAll();

quint16 *data = (quint16*) byteArray.data();

データを読み取るだけで変更したくない場合は、最後の行を次のように変更することで、プログラムを大幅に高速化できます。

const quint16* data = (const quint16*) byteArray.constData();

ただし、この (やや醜い) コードでは、ポインターは QByteArray オブジェクトの存続期間中のみ有効であることに注意してください。dataこれは通常、関数の最後までしか使用できないことを意味します。

データをそれよりも長く保持したい場合は、配列を割り当てて直接読み取る必要があります。

QFile in(fileName);
in.open(QFile::ReadOnly);
int len = in.size();

quint16 *data = new quint16[len/2];
in.read((char*)data, len);

このようにして、 までデータにアクセスできますdelete[] data

最後に、サブ質問に答えるために、配列はグローバルに定義されている場合にのみゼロで初期化されます (これに依存するべきではありません)。newまたはで割り当てられた配列mallocは、パフォーマンス上の理由からゼロで初期化されることはありません。

于 2013-01-12T19:18:53.990 に答える
0

のドキュメントを見るQDataStreamと、ループを使用したくない場合に検討する価値のある、自由に使える他の 2 つの方法があることがわかります。

これらの問題は、あなたが望むようcharにではなく、(バイト)で動作することです。quint16

ループを使用してquint16s を読み取ることをお勧めします。一番わかりやすいコードになります。また、基礎となる適切なストリームの実装は、ハードウェアからバッファーに先読みされるため、連続する多くの>>呼び出しがそれほど高価になることはありません。

于 2013-01-12T18:54:00.847 に答える