简体   繁体   中英

Trouble reading Binary file in C++

I am currently working on program that can read a binary file. I know there are a lot of topics answering that same question, but my problem is quite singular and I havent found any answer to it.

So I know the structurre of the binary file :

  • 4 bytes : Number of tables in the file Then the first table in the file:
  • 4 bytes : type of data in the table
  • 4 bytes : length of the name of the table
  • L bytes : name of the table
  • 4 bytes : number of lines
  • 4 bytes : number of columns
  • Nbr of lines * Nbr of columns * sizeof(type) bytes : Data

So using the read instruction I managed to obtain everything until the data. On my first binary file for example my first table is floating numbers 3 lines and 300 000 columns. I manage to get the first 66 then I get an endofFile flag on the 67th and bad byte flag for all the 899 932 other floats I try to read.

Here is some parts of my code for the headers (that work well)

uint32_t tableManager::getNbrTables()
{   
    uint32_t a;
    file.read(reinterpret_cast<char *>(&a), sizeof(a));
    return a;
}

uint32_t tableManager::getTypeData(int k)
{   
    uint32_t a;
    file.read(reinterpret_cast<char *>(&a), sizeof(a));
    return (a - 1);
}

These get me the right values for the headers I need. Then I use a loop to obtain the data values with the following code :

vector<vector<float>> tmpL(nbrL[m]);
    vector<float> tmpC(nbrC[m]);    
    switch (typeData[m])
    {
    case 0: 
        char x0;
        for(int n = 0; n < nbrL[m]; n++)
        {
            for(int o = 0; o < nbrC[m]; o++)
            {               
                file.read(reinterpret_cast<char *>(&x0), sizeof(x0));
                tmpC.push_back(x0);
            }
            tmpL.push_back(tmpC);
        }
        dataT.push_back(tmpL);
        break;
    case 1:
        float x1;
        for(int n = 0; n < nbrL[m]; n++)
        {
            for(int o = 0; o < nbrC[m]; o++)
            {               
                file.read(reinterpret_cast<char *>(&x1), sizeof(x1));
                tmpC.push_back(x1);
            }
            tmpL.push_back(tmpC);
        }
        dataT.push_back(tmpL);
        break;
    }

On this call of the function m = 0 which means its the first of two tables in the data.

But what I don't get is why the beginning of the data reading works and then stops working after a few reading. Depending on which binary file I use, the headers are always read correctly, but the number of float numbers read vary, even though at least two are read.

I tried to use seekg() to place manually the reading point but it does exactly the same.

Thank you for your answers if you find something or if you need more info

On Windows you need to open the file with the "b" flag to make sure text interpretation doesn't happen. There are significant changes that happen in text mode:

  1. The combination \\x0d\\x0a gets converted to \\x0a . (Or perhaps \\x0d gets dropped altogether, I forget).
  2. \\x1a is considered end-of-file and reading stops.

Both of these will be fatal when trying to read binary data. Binary data is essentially random, so you have a 1/65536 chance of hitting the first condition and 1/256 chance of hitting the second!

Most other OS's don't distinguish between binary and text mode, so you won't run into this problem on those platforms.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM