3

gzread からの呼び出しに由来する cstring を取得しました。データがブロックであり、各ブロックが unsigned int、char、int、および unsigned short int で構成されていることはわかっています。

だから、このcstringを適切な変数に分割する標準的な方法は何だろうと思っていました。

最初の 4 バイトは unsigned int、次のバイトは char、次の 4 バイトは signed int、最後の 2 バイトは unsigned short int です。

//Some pseudocode below which would work
char buf[11];
unsigned int a;
char b;
int c;
unsigned short int d;

適切なオフセットを使用して、memcpy を実行できると思います。

memcpy(&a, buf, sizeof(unsigned int));
memcpy(&b, buf+4, sizeof(char));
memcpy(&c, buf+5, sizeof(int));
memcpy(&d, buf+9, sizeof(unsigned short int));

それとも、いくつかのビット演算子を使用する方が良いですか? シフトとマスキングのように。

それとも、11 バイトすべてを何らかの構造体に直接 gzreading する方がよいでしょうか、それとも可能でしょうか? 構造体のメモリ レイアウトは修正されていますか? これは gzread で機能しますか?

4

4 に答える 4

2

ファイルのバイト順が、コードを実行しているプロセッサ アーキテクチャと一致していることを確認する必要があります。たとえば、整数が最初に最上位バイトでファイルに書き込まれ、プロセッサが最下位バイトを最初に使用する場合、結果のガベージが得られます。

コードをあるアーキテクチャから別のアーキテクチャに移植できるようにする場合は、ターゲット プロセッサのアーキテクチャに応じて、バイト オーダーを管理するマクロまたはインライン関数の背後にある整数のすべての読み取りおよび書き込み操作をラップする必要があります。

于 2011-10-11T05:57:25.083 に答える
2

構造体をパックする (__packed__属性を読み取る) 場合、順序とメンバーが整列していないことに依存できます。したがって、構造体を直接読み取ることができます。ただし、このソリューションの移植性についてはわかりません。

それ以外の場合は、ポインター マジックとキャストを次のように使用します。

char *buffer;
int a = *(reinterpret_cast<int*> (buffer))
unsigned short b = *(reinterpret_cast<unsigned short*> (buffer + sizeof(int)))
于 2011-10-11T05:48:51.813 に答える
1

入力データの定義方法によって異なります。ホスト エンディアン順であると定義されている場合 (つまり、コードが実行されているシステムとエンディアンが常に一致するmemcpy()場合)、示した は、使用するのに適した移植可能な方法です。

あるいは、入力データが特定のエンディアンを持つように定義されている場合、最適な移植可能なソリューションはunsigned char、シフトとビットごとの OR を使用して一度に 1 つずつロードすることです。

于 2011-10-11T06:34:24.693 に答える
1

何かを行う前に、フォーマットの仕様が必要です。それはテキストですか、それともバイナリですか (おそらくあなたの説明からはバイナリですが、わかりません)? 符号付きの値に使用される表現は何ですか? バイトオーダーとは何ですか? memcpyほとんどすべてのネットワーク形式がビッグ エンディアンであり、最も普及しているアーキテクチャはリトル エンディアンであるため、今日ではまれなケースです。(今日のほとんどの形式とアーキテクチャは、負の値に 2 の補数を使用するため、多くの場合、互換性を「想定」できます。ただし、例外もあります。)

これを考えると、値の数学的再構成 (マスキングとシフト、または乗算を使用) が唯一の移植可能なソリューションです。マシンとコンパイラの品質によっては、パフォーマンスも簡単に向上する可能性があります。

于 2011-10-11T07:51:03.020 に答える