Reading and writing to binary file in C++

21,746

First, your writing / reading in binary format should work like this (here read_num would contain 10 after this reading sequence).

   FILE* fp = fopen("file.bin", "wb");
   int num = 10;
   fwrite(&num, sizeof(int), 1, fp);
   fclose(fp);

   FILE* fp2 = fopen("file.bin", "rb");
   int read_num;
   fread(&read_num, sizeof(int), 1, fp2);
   fclose(fp2);

Also to mention, this way of writing is not the C++ way, but is the C way. C++ way of file operations means streams, see the following sample:

#include <fstream>
#include <string>

struct data_structure {
   std::string name;
   std::string description;
   int number;

   void save(const std::string& filename) {
      std::ofstream file(filename.c_str());
      file << name.c_str() << std::endl
           << description.c_str() << std::endl
           << number;
   }
   void load(const std::string& filename) {
      std::ifstream file(filename.c_str());

      getline(file, name);
      getline(file, description);
      file >> number;
   }
};

int main() {
   data_structure d, loaded_d;
   d.name = "Name";
   d.description = "Description";
   d.number = 5;

   d.save("file.out");
   loaded_d.load("file.out");

   return 0;
}
Share:
21,746
Reem
Author by

Reem

Updated on July 09, 2022

Comments

  • Reem
    Reem almost 2 years

    I need to make a file that contains "name" which is a string -array of char- and "data" which is array of bytes -array of char in C++- but the first problem I faced is how to separate the "name" from the "data"? newline character could work in this case (assuming that I don't have "\n" in the name) but I could have special characters in the "data" part so there's no way to know when it ends so I'm putting an int value in the file before the data which has the size of the "data"! I tried to do this with code as follow:

    if((fp = fopen("file.bin","wb")) == NULL)
    {
        return false;
    }
    char buffer[] = "first data\n";
    fwrite( buffer ,1,sizeof(buffer),fp );
    int number[1];
    number[0]=10;
    fwrite( number ,1,1, fp );
    char data[] = "1234567890";
    fwrite( data , 1, number[0], fp );
    fclose(fp);
    

    but I didn't know if the "int" part was right, so I tried many other codes including this one:

    char buffer[] = "first data\n";
    fwrite( buffer ,1,sizeof(buffer),fp );
    int size=10;
    fwrite( &size ,sizeof size,1, fp );
    char data[] = "1234567890";
    fwrite( data , 1, number[0], fp );
    

    I see 4 "NULL" characters in the file when I open it instead of seeing an integer. Is that normal? The other problem I'm facing is reading that again from the file! The code I tried to read didn't work at all :( I tried it with "fread" but I'm not sure if I should use "fseek" with it or it just read the other character after it.

    I thought of using a class as following and then writing and reading it back:

    class Sign
    {
    public:
    char* name;
    int size;
    char* data;
    };
    

    but that was not an easy thing in C++ !!

    I also tried the following:

    void saveData(char* filename) {
    
        fstream filestr;
        int n;
        n=10;
        char* data= "1234567890";
    
        filestr.open (filename, fstream::out | fstream::binary);
        for (int j = 0; j<5 ; j++)
        {
           filestr << n;
    
           for (int i = 0; i < n; i++) {
                filestr << data[i];
           }
        }
        filestr.close();
    }
    
    void readData(char* filename) {
        fstream filestr;
        int n =0;
    
        filestr.open (filename, fstream::in | fstream::binary);
        int m =0;
        //while(!filestr.eof())
        while(m<5)
        {
            filestr >> n;
    
            char *data = new char[n];
            for (int i = 0; i < n; i++) {
                filestr >> data[i];
            }
            printf("data is %s\n",data);
            m++;
        }
        filestr.close();
    }
    

    But the reading didn't work either.

    On reading I'm getting strange characters.


    So far the code that works for me is this:

    void saveData(char* filename) {
        fstream filestr;
        char * name = "first data\n";
        int n;
        n=10;
        char* data= "asdfghjkl;";
    
        filestr.open (filename, fstream::out | fstream::binary);
        for (int j = 0; j<5 ; j++)
        {
            filestr << name;
            filestr << strlen(data);
            filestr << data;
        }
        filestr.close();
    }
    
    
    void readData(char* filename) {
        fstream filestr;
        int n =0;
    
        filestr.open (filename, fstream::in | fstream::binary);
        while(!filestr.eof())
        {
            string name;
            getline(filestr,name,'\n');
            printf("name is %s\n",name.c_str());
    
            filestr >> n;
    
            char *data = new char[n];
            for (int i = 0; i < n; i++) {
                filestr >> data[i];
            }
            printf("n is%d\ndata is %s\n",n,data);
        }
        filestr.close();
    }
    

    but the problems in reading are:

    1- (I don't think it's a real problem) it prints other characters in addition to the actual data. 2- on readData function I get the output 6 times (in the last time I get every field as an empty field) while I have written only 5 times! Anyone knows why is that? is that related to while(!filestr.eof()) ??

    Thanks for help