0

fstream を使用してバイナリ ファイルを読み取っていますが、奇妙なことに、コードを実行するたびに同じ入力ファイルに対して異なる値が得られます。

if(fs->is_open())
  {
    while (!fs->eof())
    {
      fs->seekg( pos );
      fs->read( (char *)&mdfHeader, sizeof(mdfHeader_t) );
      pos += mdfHeader.length;
      fs->read( (char *)&eventHeader, sizeof(eventHeader_t) );
      fs->read( (char *)&rawHeader, sizeof(rawHeader_t) );

      fs->read( (char *)&ingressHeader, sizeof(ingressHeader_t) );

      fs->read( (char *)&l1Header_xc0, sizeof(l1Header_xc0_t) );

      fs->read(data, dataLength);
      printf("Data=%#x\n",data);

      std::cout << "counter: " << c << "\n";
      c++;
    }

    fs->close();

  }

ご覧のとおり、毎回同じはずのデータを出力しますが、異なる値が得られます。mdfHeader.length は、データの 1 ブロックの長さです。

4

2 に答える 2

2

最初に変更する項目は次のとおりです。

  1. この条件eof()は、データの読み取りが失敗した理由を特定する場合にのみ役立ちますが、ループの条件としては役に立ちません。
  2. 読み終わったら、目的のデータが正常に読み込まれたことを確認する必要があります。

つまり、ループは次のようになります。

while (*fs) {
    // read data from fs
    if (*fs) {
        // do something with the data
    }
    else if (!fs->eof()) {
        std::cout << "ERROR: failed to read record\n";
    }
}

また、シークは不要であり、それらを取り除くことをお勧めします。シークはバッファを失うため、比較的コストがかかります。コード全体を示したわけではありませんが、 の初期値にposはある程度のランダム性を提供する可能性があります。また、読み取っているバイトのシーケンスが、コンピューターでのデータの配置方法と一致していると想定します。通常はそうではなく、たとえば、さまざまなサイズの単語、さまざまなエンディアン、パディングなどに対応するために、バイナリ形式を調整する必要があります。

于 2012-10-19T14:50:24.830 に答える
1

コンピューターは数学のようなもので、すべてが確実です (rand入力が同じ場合、出力も以前と同じであるような関数でさえ) したがって、同じ入力と状態でコードを 100 回実行すると、確実に同じ出力が得られます。入力または実行状態が変更されました。

入力はコードを実行するたびに同じだと言うので、変更されるのは実行状態だけです(たとえばmalloc、プログラムを実行するたびに2つの異なる値を返す場合があります。これは、状態が異なるため、異なる状態で動作する可能性があるためです) OSによって示されます)。

コードではprintf("Data=%#x\n",data);データを出力するために使用しますが、実際にはデータのアドレスを HEX 値として出力するだけなので、プログラムを複数回実行すると、OS がエグゼクティブを別の位置などにマップするため、このアドレスが変更されることは非常に自然です。の内容を出力する必要がdataあります。以前の実行と同じになることがわかります。

于 2012-10-19T14:51:02.633 に答える