简体   繁体   中英

Read write a struct to binary files

The write/read is not giving the proper results.

Can you please tell me why the second & third record is not displayed properly.

Also how to know how many records a binary file contains?

Please see the code below

  #include <iostream.h>
  #include <fstream.h>
  #include <string.h>

  enum Ticket_type { ADULT, CHILD, STUDENT, SENIOR, FREE, SPECIAL };

  typedef struct transaction_stru
  {
    char  ID[10];
    int   tariff;
    Ticket_type  tickettype;
    int   qty;
    float total;
  }transaction_t;

 int main () {    
   // Attempt to open it for reading.
   fstream fs("trans.dat", ios::in);
   if (!fs)
      fs.open("trans.dat", ios::out | ios::binary | ios::app);     
   else{
     fs.close(); // File exists; close and reopen for write.
     transaction_t dailytrans[3];    
     dailytrans[0] = {"00001", 20, STUDENT, 1, 20.00 };
     dailytrans[1] = {"00002", 30, ADULT, 2, 60.00 };
     dailytrans[2] = {"00003", 30, SPECIAL, 3, 30.00 };    
     fs.open("trans.dat", ios::out | ios::binary | ios::app);
     fs.write((char*)&dailytrans,sizeof(dailytrans));
     fs.close();
    }

    // Let us read the file now
    fs.open("trans.dat", ios::in | ios::binary);
    if(!fs){
      cout << "Error Opening trans.dat";
      //throw SomeFileException;
    }

     transaction_t results[3]; 
     fs.read((char*)&results,sizeof(transaction_stru));
     for (size_t i=0; i < 3; i++)
      {
         cout << results[i].ID << endl;
         cout << results[i].tariff << endl;
         cout << results[i].tickettype << endl;
         cout << results[i].qty  << endl;
         cout << results[i].total << endl;
     }
     return 0;
   }

Output is get is as follows:-

   00001
   20
   2
   1
   20
   ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠00001
   -858993460
   -858993460
   -858993460
   -1.07374e+008
   ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠00001
   -858993460
   -858993460
   -858993460
   -1.07374e+008
   Press any key to continue

You seem to write and read just one struct, but print 3. Last two are therefore garbage from stack.

Additionally, it would be prudent to zero out at least ID , preferably entire struct, to avoid undefined bytes in disk file (uninitialised bytes of ID in this case), for example for your particular code in question:

memset (dailytrans, 0, sizeof(dailytrans)); // this depends on dailytrans size being known at compile time

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