2016-08-05 39 views
0

私は、符号なし__int8'ersのランダムシーケンスを作成するためにジェネレータを使用し、このメソッドでofstream.write()を使用してファイルに書き込みます。 const static unsigned __int8 BCD_SEPARATOR = 0xff;C++のfilestreamを使用して、符号なし__int8配列をバイナリファイルに読み書きする方法

void CDataGenerator::GenerateRandom(std::string outputFileName, int length, bool UseEntireRange, int max) { 
    std::ofstream file; 
    file.open(outputFileName, std::ifstream::out | std::ifstream::binary); 
    int count = 0; 
    unsigned __int8* buf = new unsigned __int8[length]; 
    while (count < length-1) { 
     int number = 0; 
     if (UseEntireRange) 
      number = rand(); 
     else { 
      int rnd = rand(); 
      number = (int)((double)rnd/RAND_MAX * max); 
     } 
     int capacity = 0; 
     if (number == 0) 
      capacity = 1; 
     else 
      capacity = (int)(floor(log10(number)) + 1); 
     for (int i = 0; i < capacity; ++i) { 
      if (count >= length - 2) 
       break; 
      buf[count] = ((unsigned __int8)(number/(int)pow(10, capacity - i - 1))); 
      number %= (int)pow(10, capacity - i - 1); 
      ++count;    
     }  
     ++count; 
     buf[count] = BCD_SEPARATOR; 
    } 
    file.write((__int8*)&buf[0], length); 
    delete[] buf; 
    file.close(); 
} 

それから私は私のテストgeneraterこの を0x0の0xFFの0x5の0x6には0xFFの0x1のを0x9は0xFF 0x8の0xFFでのようなシーケンスを作成し、イム

unsigned __int8* CModel::GetRawData(std::string inputFileName, int &length) { 
    std::ifstream file(inputFileName, std::ifstream::ate | std::ifstream::binary); 
    length = file.tellg(); 
    file.close(); 
    file.open(inputFileName, std::ifstream::in | std::ifstream::binary); 
    unsigned __int8* result = new unsigned __int8[length]; 
    file.read((__int8*)&result[0], length); 
    file.close(); 
    return result; 
} 

次の方法でファイルを読み取ろう しかし、ストリームを読むから 0x0 0xCD 0x5 0x6 0xCD 0x1 0x9 0xCD 0x8 0xCD シーケンス。 すべての0xffが0xcdに置き換えられていることは間違いありません。それは(__int8 *)キャストと結びついていますか?どうすれば解決できますか?

+1

あなたがバイナリエディタでファイルを見て、それが適切な値で書かれています:

問題を解決するには、単に次のように周りのものを交換するだろうか? –

+0

読み書きが成功したことを確認しましたか?その*ファイルを開く*が成功しましたか? –

+0

また、コンパイラ固有のものではなく、int8_t'from [''](http://en.cppreference.com/w/cpp/header/cstdint)のような標準の固定幅の整数型を使用することをお勧めします-portable '__int8'です。 C++でCスタイルのキャストを使用することをお勧めします。代わりに 'reinterpret_cast (result)'のようなものを使用してください。これらの事のどれもあなたの問題に関連してはいけません。 –

答えて

3

Visual Studioで使用されているCRTデバッグヒープについて知っていれば(私はVisual Studioを使用していると仮定しています)、0xCD値は初期化されていないヒープメモリからのものです。その質問は次のようになります。なぜあなたはこれを出力に見ていますか?理由を理解するには、デバッガを使用してGenerateRandom関数を実行するか、コードを読んでください。このことから

問題がどこにあるか、それが明らかになった:

for (int i = 0; i < capacity; ++i) { 
    if (count >= length - 2) 
     break; 
    buf[count] = ((unsigned __int8)(number/(int)pow(10, capacity - i - 1))); 
    number %= (int)pow(10, capacity - i - 1); 
    ++count; //Increment count ONCE 
} 

++count; //Increment count a SECOND time 
buf[count] = BCD_SEPARATOR; 

問題は、プログラムがここに示されているforループを離れたとき、あなたの「カウント」はあるので、カウントはすでに、一度インクリメントされているということですバッファ内の次の初期化されていない__int8に既にあります。その後、BCD_SEPARATORをバッファの "count"の位置に書き込む前に、再度 "count"をインクリメントします。これにより、実際にBCD_SEPARATORが必要な位置がスキップされます。

次の問題は、バッファにBCD_SEPARATORを書き込んだ後、次回にforループを入力した後に "count"を増やさないため、すぐにBCD_SEPARATORを上書きします。

buf[count] = BCD_SEPARATOR; 
++count; 
関連する問題