1

I want to open a file, read the first 5 bytes, check that the first 4 match a given signature and the 5th is the size of my file header. The size of the header is what i am surposed to read next to get the build of the rest of the data.

What ive tried so far:

#include <iostream>
#include <fstream>
#include <vector>
#include <string>

typedef struct file_header{
    char signature[4];
    unsigned char size;
    char version;
    //Different other things left out for example matters.
    unsigned int blocks;
    unsigned int block_size;
} header;

void open_file(std::string fileName, header &header){
    std::ifstream fIn;
    fIn.exceptions(std::ifstream::failbit | std::ifstream::badbit);
    char buffer[5];
    try{
        fIn.open(fileName, std::ios::binary);
        //read the 1st 5 bytes to get header signature and header size
        fIn.read(buffer, 5);
        header.size = buffer[4];

        //Here my problems begins...
        fIn.seekg(0, std::ios::beg);
        std::vector<char*> header_data;
        header_data.reserve((int)header.size);

        //How do i read the first (int)header.size bytes of file to Vector?
        fIn.read(header_data[0], (int)header.size); //Wont work?

    }catch(std::ifstream::failure ex){
        std::cerr << ex.code().message() << std::endl;
        exit(0);
    }
}

int main(int argc, char* argv[]){
    char* filename = argv[1];
    file_header header;
    open_file(filename, header);
    return 0;
}

I have just started with c++ not so long ago, but in Java, i can do something neat like:

char header_size[(int)header.size];

But what i found out so far, is that you can't make dynamic arrays in c++ therefore the vector.

What can i do to get the output i need?

The code ive written give a Vector out of range, i guess the [0] does that?

Any help or pointers appreceated..

FastDuck
  • 57
  • 1
  • 1
  • 6

2 Answers2

0

You should do vector_data.resize(header.size), because reserve, just reserves memory, which doesn't mean that this vector contains valid objects (so you can't access anything).

Take a look at this SO question about the difference between std::vector<T>::resize and std::vector<T>::reserve.

Also, you're allocating memory for header.size elements of type char *, but all of them are uninitialized, so when you try to read into one of them, you're reading into nowhere, which will result in a segmentation fault. First allocate memory for each pointer with new char[some_size].

Community
  • 1
  • 1
ForceBru
  • 43,482
  • 10
  • 63
  • 98
  • Changed the vector declaration to: `std::vector header_data;` the reserve to resize and my read line to: `fIn.read(&header_data[0], (int)header.size);` That did it! Thanks! – FastDuck Jun 02 '16 at 11:57
0

Once you've read the header, the file pointer is positioned ready to read the bytes following it. fIn.seekg(0, std::ios::beg); will move the file pointer back to the beginning, which you don't want.

fIn.read(buffer, 5);
header.size = buffer[4];
char * header_data = new char[header.size];
fIn.read(header_data, (streamsize)header.size);

You'll have to free the memory allocated to header_data when you're finished with it

delete[] header_data;
John D
  • 1,627
  • 1
  • 11
  • 10