1

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

6
  • 2
    On Windows you need to open the file with the "b" flag to make sure text interpretation doesn't happen. Commented Apr 6, 2017 at 15:41
  • wow thanks a lot, I was sure I did , i must have changed that earlier today ... Sorry for the long post then ! I am new to stack overflow how do I accept the answer ? Commented Apr 6, 2017 at 15:45
  • There should be an "accept" button. Commented Apr 6, 2017 at 15:54
  • 1
    I am new to stack overflow -- Well I give you kudos for actually doing legitimate, well thought-out, binary file reading / writing. A lot of the questions here concerning this involve saving STL containers and std::strings in a binary file, and wondering why the program doesn't read / write properly. Commented Apr 6, 2017 at 16:34
  • Are the values in Big Endian or Little Endian order? Commented Apr 6, 2017 at 16:36

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.