2016-08-05 5 views
0

Ich benutze Generator, um eine zufällige Sequenz von unsignierten __int8'ers zu machen, und dann schreibe sie in Datei mit ofstream.write() mit dieser Methode;Wie liest und schreibt man unsigniertes __int8-Array in Binärdatei mit Filestream in C++

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(); 
} 

Wo const static unsigned __int8 BCD_SEPARATOR = 0xff;

Dann versuche ich Datei zu lesen, mit der Methode folgenden

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; 
} 

Im meinem Test generater schafft Sequenz wie diese 0x0 0xFF 0x5 0x6 0xFF 0x1 0x9 0xFF 0x8 0xFF aber aus dem Lesestrom bekomme ich 0x0 0xCD 0x5 0x6 0xCD 0x1 0x9 0xCD 0x8 0xCD Sequenz. Es ist offensichtlich, dass alle 0xff durch 0xcd ersetzt werden. Ist es verbunden mit (__int8 *) Casts und wie löse ich es?

+1

Wenn man sich die Datei in einem Hex-Editor aussehen, hat es mit den richtigen Werten geschrieben worden? –

+0

Haben Sie überprüft, ob das Lesen oder Schreiben erfolgreich war? Das * Öffnen * der Datei ist gelungen? –

+0

Auch ich schlage vor, dass Sie die Standard-Integer-Typen mit fester Breite wie 'int8_t'from [' '] (http://en.cppreference.com/w/cpp/header/cstdint) anstelle des Compiler-spezifischen und nicht verwenden -portable '__int8'. Ich empfehle auch C-Style-Cams in C++ zu verwenden. Verwenden Sie stattdessen etwas wie "reinterpret_cast (result)". Keines dieser Dinge sollte sich jedoch auf Ihr Problem beziehen. –

Antwort

3

Mit Wissen über den CRT-Debug-Heap, den Visual Studio verwendet (ich nehme nur an, dass Sie Visual Studio verwenden), ist es eine gute Schätzung, dass der 0xCD-Wert aus nicht initialisiertem Heapspeicher stammt. Die Frage wird dann: Warum siehst du das in der Ausgabe? Um herauszufinden, warum, können Sie einfach Ihre GenerateRandom-Funktion mit Ihrem Debugger durchlaufen/den Code lesen.

Daraus wird deutlich, wo das Problem liegt:

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; 

Das Problem ist, dass, wenn das Programm verlässt die for-Schleife hier gezeigt, haben zählen bereits einmal erhöht worden, so dass Ihre „count“ ist schon beim nächsten nicht initialisierten __int8 im Puffer. Dann inkrementieren Sie "count" noch einmal, bevor Sie BCD_SEPARATOR in die "count" -Position im Puffer schreiben. Dies führt dazu, dass das Programm die Position überspringt, an der Sie eigentlich Ihren BCD_SEPARATOR haben möchten.

Das nächste Problem wird dann, dass Sie nicht "count" zwischen dem Schreiben des BCD_SEPARATORs in den Puffer und dem nächsten Mal, wenn Sie die oben gezeigte for-Schleife eingeben, den BCD_SEPARATOR überschreiben.

könnte eine Lösung für das Problem tauschen, die Dinge einfach um wie folgt aus:

buf[count] = BCD_SEPARATOR; 
++count; 
Verwandte Themen