5

外部グループは、ビッグエンディアンマシンで記述されたファイルを提供してくれます。また、ファイル形式用のC++パーサーも提供しています。

リトルエンディアンのマシンでのみパーサーを実行できます-読み取るたびにswapbytes()呼び出しを追加せずに、パーサーを使用してファイルを読み取る方法はありますか?

4

8 に答える 8

13

鉄器時代の初期に、古代人は原始的なPDP-11ミニコンピューターを他の原始的なコンピューターとネットワーク化しようとしたときにこの問題に遭遇しました。PDP-11は最初のリトルエンディアンのコンピューターでしたが、当時の他のほとんどのコンピューターはビッグエンディアンでした。

この問題を解決するために、彼らはネットワークバイトオーダーの概念(常にビッグエンディアン)と、対応するネットワークバイトオーダーマクロntohs()、ntohl()、htons()、およびhtonl()を開発しました。これらのマクロで記述されたコードは、常に「正しい答えを得る」でしょう。

外部のサプライヤに頼って、コードでマクロを使用してください。マクロが提供するファイルは、リトルエンディアンのマシンに切り替えた場合でも、常にビッグエンディアンになります。マクロを使用するために提供されたパーサーを書き直してください。ビッグエンディアンのマシンに切り替えた場合でも、常にファイルを読み取ることができます。

この特定の問題に、本当に途方もない量のプログラマー時間が浪費されてきました。リトルエンディアンの機能を決定したPDP-11設計者をぶら下げることについて、良い議論ができると思う日があります。

于 2010-01-07T18:27:08.687 に答える
4

次のコードを含めるようにパーサーチームを説得してみてください。

int getInt(char * bytes、int num)
{{
    int ret;
    assert(num == 4);
    ret = bytes [0] << 24;
    ret|=バイト[1]<<16;
    ret|=バイト[2]<<8;
    ret|=バイト[3];
    retを返します。
}

一般的なシステムよりも時間がかかる場合がありますがint i = *(reinterpret_cast<*int>(&myCharArray));、大小のエンディアンシステムの両方で常にエンディアンが正しくなります。

于 2010-01-07T18:19:45.627 に答える
2

それはあなたがデータで何をしているのかに依存します。データを出力する場合は、すべての数値のバイトを交換する必要があります。ファイルで1つ以上の値を探している場合は、比較値をバイトスワップする方が速い場合があります。

一般的に、グレッグは正しいです、あなたはそれを難し​​い方法でしなければならないでしょう。

于 2010-01-07T18:09:29.160 に答える
2

一般に、これに対する「簡単な」解決策はありません。ファイルから読み取られたすべての整数のバイトを交換するようにパーサーを変更する必要があります。

于 2010-01-07T18:06:23.580 に答える
2

最善のアプローチは、エンディアンをファイル形式で定義することであり、マシンに依存しているとは言わないことです。ライターは、実行中のCPUに関係なく、正しい順序でバイトを書き込む必要があり、リーダーも同じことを行う必要があります。

于 2010-01-07T18:19:06.483 に答える
0

パーサーを変更したくない場合は、パーサーをラップしてバイトを反転するパーサーを作成できます。

読み込まれるデータの種類に注意してください。4バイトintまたはfloatエンディアン補正が必要になります。4バイトのASCII文字列はそうではありません。

于 2010-01-07T18:11:13.837 に答える
0

一般的に、いいえ。

読み取り/書き込み呼び出しがタイプ認識されていない場合(たとえば、freadとfwriteは認識されていない場合)、エンディアン機密データの書き込みとエンディアン非機密データの書き込みの違いを区別できません。

パーサーの構造によっては、問題を回避できる場合があります。使用するI / O関数が読み取り/書き込みの型を認識している場合は、これらのルーチンを変更して、正しいエンディアン変換を適用できます。

すべての読み取り/書き込み呼び出しを変更する必要がある場合は、そのようなルーチンを作成するのが賢明な行動です。

于 2010-01-07T18:12:24.377 に答える
0

あなたの質問はどういうわけか答えを含みます:いいえ!

リトルエンディアンのマシンでのみパーサーを実行できます-読み取るたびにswapbytes()呼び出しを追加せずに、パーサーを使用してファイルを読み取る方法はありますか?

リトルエンディアンのマシンでビッグエンディアンのデータを読み取る(そして解釈したい)場合は、何らかの方法でどこかでデータを変換する必要があります。これは、各読み取り後、またはファイル全体が読み取られた後に行うことができます(読み取られたデータにそれ以上のデータの読み取り方法に関する情報が含まれていない場合)。ただし、変換を省略する方法はありません。

于 2010-01-07T21:12:04.253 に答える