Ok guys, for my next assignment I have to read from a binary file and then print out my information. I will post the assignment and what I have so far. But my question is, do I create the binary file first in the program or by hand or what?? I have read from a text file before but never a binary file.

1) Modify your program to read the initial list of cars in inventory from a data file that you create. It must read the saved cars into your array as it loads. The file must be stored in binary.

2) Once again. The file must be stored in binary.

3) The program must check for problems opening the binary data file and give an appropriate message to the user if it cannot open the file.

4) If the program doesn’t change the cars in the array in any way (I think they all do but just in case the one you select does not,) prompt the user for a change to the make and model of the second car in the array.

5) At the end of the program save the cars to the binary data file for the next program run.

Class

#include <iostream>
#include <fstream>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <sstream>
using namespace std;

//Vehicle Class
class Car
{
protected:
    string make;  //make
    string model; // model
    string color;  // color
    int    year;  // year
    int mileage;  // miles on car

public:
        //Constructor that will set information for a new car
    void New_vehicle (string a, string b, string c, int d, int e)
    {make = a; model = b; color = c; year = d; mileage = e;;}
   
    Car(); //Default constructor
    Car(string, string, string, int, int);
    //mutator and accessor functions
    void setMake(string);
    void setModel(string);
    void setColor(string);
    void setYear(int);
    void setMileage(int);


    string getMake();
    string getModel();
    string getColor();
    int getYear();
    int getMileage();


    //Check mileage to see if valid
    void valid_mileage(int);
    void car_details();
    string string_car_details();
};

//Sets to default values
Car::Car() {
    make = " ";
    model = " ";
    color = " ";
    year = 0;
    mileage = 0;
}
    // My Vehicle set up(Make, model, color, year, type,bedsize, bike, mileage)
Car::Car(string make, string model, string color, int year, int mileage) {
    Car::make =  make;
    Car::model = model;
    Car::color = color;
    Car::year = year;
    valid_mileage(mileage);

}

void Car::setMake(string make) {
    Car::make = make;
}

void Car::setModel(string model) {
    Car::model = model;
}

void Car::setColor(string color) {
    Car::color = color;
}

void Car::setYear(int year) {
    Car::year = year;
}

void Car::setMileage(int mileage) {
    valid_mileage(mileage);
}


string Car::getMake() {
    return make;
}
string Car::getModel() {
    return model;
}
string Car::getColor() {
    return color;
}
int Car::getYear() {
    return year;
}
int Car::getMileage() {
    return mileage;
}


void Car::valid_mileage(int mileage) {
    if (mileage>=0)
        Car::mileage=mileage;
    else {
        Car::mileage=0;
        cout << "WARNING! You have entered invalid mileage!\n";
    }
    }

    void Car::car_details() {
        cout << "The current car is a " << year << ' ' << color << ' '
            << make << ' ' << model << " with " << mileage << " miles.\n\n";
    }



    string Car::string_car_details() {
        stringstream buf;
        buf << "The current car is a " << year << ' ' << color << ' '
        << make << ' ' << model << " with " << mileage << " miles.\n\n";
        return buf.str();
    }

CPP

#include "CarClass.h"
#include <fstream>
#include <sys/stat.h>

using namespace std;

ifstream::pos_type size;
char * memblock;

int main () {
  ifstream file ("read.bin", ios::in|ios::binary|ios::ate);
  if (file.is_open())
  {
    size = file.tellg();
    memblock = new char [size];
    file.seekg (0, ios::beg);
    file.read (memblock, size);
    file.close();

    cout << "the complete file content is in memory";

    delete[] memblock;
  }
  else cout << "Unable to open file";
  return 0;
}

But my question is, do I create the binary file first in the program or by hand or what?? I have read from a text file before but never a binary file.

In order to read from a binary file, there must be a binary file to read from. That means that one of four things must happen:

  1. You need to be provided with a binary file from your instructor or whoever.
  2. You must create a binary file by hand.
  3. You must write a program to create the binary file yourself.
  4. You must convert a text file to a binary file that works for your format. Either write your own program or there may be some out there already.

I'd opt for option 2. It'll force you to get more familiar with what a binary file looks like. Get a hex editor program like Hex Editor Neo and make one with that. Or you are probably going to have to write some functions that write binary files anyway, so you can do those first. Then read from them.

Edited 6 Years Ago by VernonDozier: n/a

Well in our program he wants us to take an array of 3 cars, and then write them to a binary file! My question is, how will I write an array of strings and ints to a binary file??

The easiest way to create binary files is to use fixed-length character arrays instead of std::string. That will make each of the records in the binary fine the same size and you can easily locate any record in the file by simply multiplying the record number times record size.

struct record
{
    char make[40];
    char model[40];
    char color[20];
    int year;
    int mileage;
};

ofstream out("filename.bin", ios::binary);
struct record r[3];

// write three cars
out.write( (char*)r, sizeof(struct record) * 3);

// read 3 cars
ifstream in("filename.bin", ios::binary);
in.read( (char *)r, sizeof(struct record) * 3);

Edited 6 Years Ago by Ancient Dragon: n/a

Comments
Level up!

So will I need to make this change in my class file or my cpp file! And second, where will my array of three cars go??

Beats me. You are writing the program, not me. Instead of using the struct record I posted, you can easily change your car record to hold char arrays instead of std::string. Then write the array of those classes like I did the structures. You may have to write them out one at a time if you did not make an array of those classes.

So will I need to make this change in my class file or my cpp file! And second, where will my array of three cars go??

They go wherever you put them. You change them wherever they need to be changed. Not trying to be a smart-aleck here. I'm just driving home a point. A huge part of coding is taking a big step back and trying to find the design that fits your needs. You either design your input files around your methods or you design your methods around your input files. One very common reason for using binary files is to save disk space. An integer like 1234567890 takes four bytes, not 10 (one per digit), assuming an int is 4 bytes (big assumption, so don't assume), plus you don't need a space for a delimiter. But then you have to worry about stuff like Endian-consistency (or you might not).

If you are brand new to binary files, I would step away from this project and start writing a few binary files along with programs to read and write them so you can get a feel for the issues and mechanics involved.

Comments
:) driving home a point about cars - love it!

Ok guys, I spent all of yesterday understanding a binary file and creating a binary file's and I have managed to understand them pretty well and found some great websites explaining them. I have finished my code and it does not work, but I know whats wrong, I just need to know how to fix it!! I will post the code and then post my problem at the end!

Class

#include <iostream>
#include <fstream>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <sstream>
using namespace std;

//Vehicle Class
class Car
{
protected:
		char make[40];	//Make of car
      	char model[40];	//Model of car
      	char color[20];	//Color of car
      	int year;		//Year of car
      	int mileage;	//Mileage of car

public:

	Car(); //Default constructor
	Car(char, char, char, int, int);
	//mutator and accessor functions
	void setMake(char);
    void setModel(char);
    void setColor(char);
    void setYear(int);
	void setMileage(int);


    char getMake();
    char getModel();
    char getColor();
    int getYear();
    int getMileage();


	//Check mileage to see if valid
    void valid_mileage(int);
    void car_details();
    string string_car_details();
};

//Sets to default values
Car::Car() {
	make = " ";
    model = " ";
    color = " ";
    year = 0;
    mileage = 0;
}
	// My Vehicle set up(Make, model, color, year, type,bedsize, bike, mileage)
Car::Car(char, char model, char color, int year, int mileage) {
	Car::make =  make;
	Car::model = model;
	Car::color = color;
	Car::year = year;
    valid_mileage(mileage);

}

void Car::setMake(char make) {
    Car::make = make;
}

void Car::setModel(char model) {
    Car::model = model;
}

void Car::setColor(char color) {
    Car::color = color;
}

void Car::setYear(int year) {
    Car::year = year;
}

void Car::setMileage(int mileage) {
    valid_mileage(mileage);
}


char Car::getMake() {
    return make;
}
char Car::getModel() {
    return model;
}
char Car::getColor() {
    return color;
}
int Car::getYear() {
    return year;
}
int Car::getMileage() {
    return mileage;
}


void Car::valid_mileage(int mileage) {
    if (mileage>=0)
        Car::mileage=mileage;
    else {
        Car::mileage=0;
        cout << "WARNING! You have entered invalid mileage!\n";
	}
    }

	void Car::car_details() {
	    cout << "The current car is a " << year << ' ' << color << ' '
			<< make << ' ' << model << " with " << mileage << " miles.\n\n";
	}



	string Car::string_car_details() {
	    stringstream buf;
	    buf << "The current car is a " << year << ' ' << color << ' '
	    << make << ' ' << model << " with " << mileage << " miles.\n\n";
	    return buf.str();
	}

CPP File

#include "CarClass.h"
#include <fstream>
#include <sys/stat.h>

using namespace std;

ifstream::pos_type size;
char * memblock;

int main () {

	struct record
	{

      char make[40];
      char model[40];
      char color[20];
      int year;
      int mileage;
      };


	const int SIZE = 3;
			
	//Array of 9 cars
	Car Car_array[SIZE] = { Car("Porsche", "911", "Silver", 2005, 18990), 
							Car("Ford", "Mustang", "Red", 2007, 49842),
							Car("Chevrolet", "Beretta", "Black", 1989, 90332)};


      ofstream out("filename.bin", ios::binary);
      struct record r[3];
      // write three cars
	  out.write( (char*)r, sizeof(struct record) * 3);

      // read 3 cars
      ifstream in("filename.bin", ios::binary);
      in.read( (char *)r, sizeof(struct record) * 3);
  return 0;
}

PROBLEM:

//Sets to default values
Car::Car() {
	make = " ";
    model = " ";
    color = " ";
    year = 0;
    mileage = 0;
}

What will I set the char's make, model, and color = to??

What will I set the char's make, model, and color = to??

Either pick a "default car" (how about "Tan Chevy Nova"), initialize it to an empty string, or initialize it to "UNINITIALIZED" to make it extra obvious. If it is specified in the spec, use that. If not, it is completely up to you.

Not sure if this is what you mean but here is what I did

//Sets to default values
Car::Car() {
	make = "UNINITIALIZED";
    model = "UNINITIALIZED";
    color = "UNINITIALIZED";
    year = 0;
    mileage = 0;
}

And I am still getting the same errors! And when I hover over make, model or color, it says "Expression must be modifiable lvalue"

Edited 6 Years Ago by tarheelfan_08: n/a

Not sure if this is what you mean but here is what I did

//Sets to default values
Car::Car() {
	make = "UNINITIALIZED";
    model = "UNINITIALIZED";
    color = "UNINITIALIZED";
    year = 0;
    mileage = 0;
}

And I am still getting the same errors! And when I hover over make, model or color, it says "Expression must be modifiable lvalue"

You have them as character arrays, not strings, so you can't use the = operator. Use strcpy from cstring:

strcpy (make, "UNINITIALIZED");

1>------ Build started: Project: FileReading, Configuration: Debug Win32 ------
1> Car.cpp
1>\filereading\carclass.h(48): error C2440: '=' : cannot convert from 'const char [14]' to 'char [40]'
1> There is no context in which this conversion is possible
1>\filereading\carclass.h(49): error C2440: '=' : cannot convert from 'const char [14]' to 'char [40]'
1> There is no context in which this conversion is possible
1>\filereading\carclass.h(50): error C2440: '=' : cannot convert from 'const char [14]' to 'char [20]'
1> There is no context in which this conversion is possible
1>\filereading\carclass.h(56): error C2106: '=' : left operand must be l-value
1>\filereading\carclass.h(57): error C2440: '=' : cannot convert from 'char' to 'char [40]'
1> There are no conversions to array types, although there are conversions to references or pointers to arrays
1>\filereading\carclass.h(58): error C2440: '=' : cannot convert from 'char' to 'char [20]'
1> There are no conversions to array types, although there are conversions to references or pointers to arrays
1>\filereading\carclass.h(65): error C2440: '=' : cannot convert from 'char' to 'char [40]'
1> There are no conversions to array types, although there are conversions to references or pointers to arrays
1>\filereading\carclass.h(69): error C2440: '=' : cannot convert from 'char' to 'char [40]'
1> There are no conversions to array types, although there are conversions to references or pointers to arrays
1>\filereading\carclass.h(73): error C2440: '=' : cannot convert from 'char' to 'char [20]'
1> There are no conversions to array types, although there are conversions to references or pointers to arrays
1>\filereading\carclass.h(86): error C2440: 'return' : cannot convert from 'char [40]' to 'char'
1> There is no context in which this conversion is possible
1>\filereading\carclass.h(89): error C2440: 'return' : cannot convert from 'char [40]' to 'char'
1> There is no context in which this conversion is possible
1>\filereading\carclass.h(92): error C2440: 'return' : cannot convert from 'char [20]' to 'char'
1> There is no context in which this conversion is possible
1>\filereading\car.cpp(24): error C2665: 'Car::Car' : none of the 3 overloads could convert all the argument types
1> \filereading\carclass.h(24): could be 'Car::Car(char,char,char,int,int)'
1> while trying to match the argument list '(const char [8], const char [4], const char [7], int, int)'
1>\filereading\car.cpp(25): error C2665: 'Car::Car' : none of the 3 overloads could convert all the argument types
1> \filereading\carclass.h(24): could be 'Car::Car(char,char,char,int,int)'
1> while trying to match the argument list '(const char [5], const char [8], const char [4], int, int)'
1>\filereading\car.cpp(26): error C2665: 'Car::Car' : none of the 3 overloads could convert all the argument types
1> \filereading\carclass.h(24): could be 'Car::Car(char,char,char,int,int)'
1> while trying to match the argument list '(const char [10], const char [8], const char [6], int, int)'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Oh ok, so will I have to do something like that here??

// My Vehicle set up(Make, model, color, year, type,bedsize, bike, mileage)
Car::Car(char make, char model, char color, int year, int mileage) {
	Car::make =  make;
	Car::model = model;
	Car::color = color;
	Car::year = year;
    valid_mileage(mileage);

}

Cause I am getting errors with this still!

Hi, VernonDozier:

Why the = operator cannot be used for the character array as you mentioned in the post.

You have them as character arrays, not strings, so you can't use the = operator. Use strcpy from cstring:

strcpy (make, "UNINITIALIZED");

Hi, VernonDozier:

Why the = operator cannot be used for the character array?

//Sets to default values
Car::Car() {
	make = " ";
    model = " ";
    color = " ";
    year = 0;
    mileage = 0;
}

What will I set the char's make, model, and color = to??

The constructor isn't quite right. To make an empty string all you have to do is set the first byte to 0.

Car::Car() {
    make[0] = '\0';
    model[0] = '\0';
    color[0] = '\0';
    year = 0;
    mileage = 0;
}

Edited 6 Years Ago by Ancient Dragon: n/a

Ok here is my new code guys, and it is creating the file that I want! But its not reading from that file and printing on the screen! IT should write the array of cars to the file, read the array of cars and print them on the screen and then re-write the array of cars..

Also, should I save this as a .bin file or a .dat file or .txt file or what??
CLASS

#include <iostream>
#include <fstream>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <sstream>

#include <sys/stat.h>


using namespace std;

//Vehicle Class
class Car
{
protected:
    char make[40];	//Make of car
    char model[40];	//Model of car
    char color[20];	//Color of car
    int year;		//Year of car
    int mileage;	//Mileage of car

public:

    Car(); //Default constructor
    Car(char* make, char* model, char* color, int, int);
    //mutator and accessor functions
    void setMake(char*);
    void setModel(char*);
    void setColor(char*);
    void setYear(int);
    void setMileage(int);


    const char* getMake();
    const char* getModel();
    const char* getColor();
    int getYear();
    int getMileage();


    //Check mileage to see if valid
    void valid_mileage(int);
    void car_details();
    string string_car_details();
};

//Sets to default values
Car::Car() 
{
    strcpy(make,"Uninitialzed");
    strcpy(model,"Uninitialzed");
    strcpy(color,"Uninitialzed");
    year = 0;
    mileage = 0;
}
// My Vehicle set up(Make, model, color, year,  mileage)
Car::Car(char* make, char* model, char* color , int year, int mileage) 
{
    strcpy(Car::make,make);
    strcpy (Car::model,model);
    strcpy(Car::color,color);
    Car::year = year;
    valid_mileage(mileage);

}

void Car::setMake(char* make) 
{
    strcpy(Car::make,make);
}

void Car::setModel(char* model) 
{
    strcpy(Car::model,model);
}

void Car::setColor(char* color) 
{
    strcpy(Car::color,color);
}

void Car::setYear(int year) 
{
    Car::year = year;
}

void Car::setMileage(int mileage) 
{
    valid_mileage(mileage);
}


const char* Car::getMake()  
{
    return make;
}
const char* Car::getModel() 
{
    return model;
}
const char* Car::getColor() 
{
    return color;
}
int Car::getYear() 
{
    return year;
}
int Car::getMileage() 
{
    return mileage;
}


void Car::valid_mileage(int mileage) 
{
    if (mileage>=0)
        Car::mileage=mileage;
    else 
    {
        Car::mileage=0;
        cout << "WARNING! You have entered invalid mileage!\n";
    }
}

void Car::car_details() 
{
    cout << "The current car is a year" << year << ' ' << color << ' '
        << make << ' ' << model << " with " << mileage << " miles.\n\n";
}



string Car::string_car_details() 
{
    stringstream buf;
    buf << "The current car is a year " << year << ' ' << color << ' '
        << make << ' ' << model << " with " << mileage << " miles.\n\n";
    return buf.str();
}

CPP File

#include "CarClass.h"
#include <fstream>
#include <sys/stat.h>

using namespace std;


int main () {

	struct record
	{

      char make[40];
      char model[40];
      char color[20];
      int year;
      int mileage;
      };


	const int SIZE = 3;
			
	//Array of 9 cars
	Car Car_array[SIZE] = { Car("Porsche", "911", "Silver", 2005, 18990), 
							Car("Ford", "Mustang", "Red", 2007, 49842),
							Car("Chevrolet", "Beretta", "Black", 1989, 90332)};


      ofstream out("binaryFile.bin", ios::binary);
      struct record r[3];
      // write three cars
	  out.write( (char*)r, sizeof(struct record) * 3);

      // read 3 cars
      ifstream in("binaryFile.bin", ios::binary);
      in.read( (char *)r, sizeof(struct record) * 3);
  return 0;
}

1>------ Build started: Project: FileReading, Configuration: Debug Win32 ------
1> Car.cpp
1>\filereading\carclass.h(48): error C2440: '=' : cannot convert from 'const char [14]' to 'char [40]'
1> There is no context in which this conversion is possible
1>\filereading\carclass.h(49): error C2440: '=' : cannot convert from 'const char [14]' to 'char [40]'
1> There is no context in which this conversion is possible
1>\filereading\carclass.h(50): error C2440: '=' : cannot convert from 'const char [14]' to 'char [20]'
1> There is no context in which this conversion is possible
1>\filereading\carclass.h(56): error C2106: '=' : left operand must be l-value
1>\filereading\carclass.h(57): error C2440: '=' : cannot convert from 'char' to 'char [40]'
1> There are no conversions to array types, although there are conversions to references or pointers to arrays
1>\filereading\carclass.h(58): error C2440: '=' : cannot convert from 'char' to 'char [20]'
1> There are no conversions to array types, although there are conversions to references or pointers to arrays
1>\filereading\carclass.h(65): error C2440: '=' : cannot convert from 'char' to 'char [40]'
1> There are no conversions to array types, although there are conversions to references or pointers to arrays
1>\filereading\carclass.h(69): error C2440: '=' : cannot convert from 'char' to 'char [40]'
1> There are no conversions to array types, although there are conversions to references or pointers to arrays
1>\filereading\carclass.h(73): error C2440: '=' : cannot convert from 'char' to 'char [20]'
1> There are no conversions to array types, although there are conversions to references or pointers to arrays
1>\filereading\carclass.h(86): error C2440: 'return' : cannot convert from 'char [40]' to 'char'
1> There is no context in which this conversion is possible
1>\filereading\carclass.h(89): error C2440: 'return' : cannot convert from 'char [40]' to 'char'
1> There is no context in which this conversion is possible
1>\filereading\carclass.h(92): error C2440: 'return' : cannot convert from 'char [20]' to 'char'
1> There is no context in which this conversion is possible
1>\filereading\car.cpp(24): error C2665: 'Car::Car' : none of the 3 overloads could convert all the argument types
1> \filereading\carclass.h(24): could be 'Car::Car(char,char,char,int,int)'
1> while trying to match the argument list '(const char [8], const char [4], const char [7], int, int)'
1>\filereading\car.cpp(25): error C2665: 'Car::Car' : none of the 3 overloads could convert all the argument types
1> \filereading\carclass.h(24): could be 'Car::Car(char,char,char,int,int)'
1> while trying to match the argument list '(const char [5], const char [8], const char [4], int, int)'
1>\filereading\car.cpp(26): error C2665: 'Car::Car' : none of the 3 overloads could convert all the argument types
1> \filereading\carclass.h(24): could be 'Car::Car(char,char,char,int,int)'
1> while trying to match the argument list '(const char [10], const char [8], const char [6], int, int)'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Wait, these errors are with YOUR code with the = operator or MY REVISED CODE with strcpy?

Oh ok, so will I have to do something like that here??

// My Vehicle set up(Make, model, color, year, type,bedsize, bike, mileage)
Car::Car(char make, char model, char color, int year, int mileage) {
	Car::make =  make;
	Car::model = model;
	Car::color = color;
	Car::year = year;
    valid_mileage(mileage);

}

Cause I am getting errors with this still!

These all need to be char*, not char. Change from this:

Car::Car(char make, char model, char color, int year, int mileage)

to this:

Car::Car(char* make, char* model, char* color, int year, int mileage)

Then, again, use strcpy, not the = operator.

strcpy (this->make, make);

You can drop the Car:: from INSIDE the constructor. Keep it here:

Car::Car(char* make, char* model, char* color, int year, int mileage)

Edited 6 Years Ago by VernonDozier: n/a

Hi, VernonDozier:

Why the = operator cannot be used for the character array as you mentioned in the post.

Because you are trying to do a DEEP COPY here, not a SHALLOW COPY, and even if the = operator here didn't result in an error, all it would do was change pointers rather than do a full deep copy. If it was a std::string rather than a C-string, it WOULD be a deep copy. But the OP here is using C-strings.

When I add cout's to see what the program is doing it just runs them together and does nothing with the read.

#include "CarClass.h"
#include <fstream>
#include <sys/stat.h>

using namespace std;


int main () {

	struct record
	{

      char make[40];
      char model[40];
      char color[20];
      int year;
      int mileage;
      };


	const int SIZE = 3;
			
	//Array of 9 cars
	Car Car_array[SIZE] = { Car("Porsche", "911", "Silver", 2005, 18990), 
							Car("Ford", "Mustang", "Red", 2007, 49842),
							Car("Chevrolet", "Beretta", "Black", 1989, 90332)};

	cout << "Writing to file\n\n";
      ofstream out("binaryFile.bin", ios::binary);
      struct record r[3];
      // write three cars
	  out.write( (char*)r, sizeof(struct record) * 3);
	  out.close();


      // read 3 cars
	  cout << "Reading file\n\n";
      ifstream in("binaryFile.bin", ios::binary);
      in.read( (char *)r, sizeof(struct record) * 3);
  return 0;
}

You need to find out for sure whether the problem is in the reading and writing to the file or if it's in something else (the class isn't storing the info correctly.

Write a display function for the class and make sure that it displays correctly (or, similarly write a << operator for the class).

void Car::Display ()
{
    // 5 cout statements
}

From your test program, set up a loop.

for (int i = 0; i < SIZE; i++)
    Car_array[i].Display ();

If that displays the correct information, then start looking at your file reading and writing. Otherwise, you need to debug the rest of your Car class.

Ok here is my code.

#include "CarClass.h"
#include <fstream>
#include <sys/stat.h>

using namespace std;


int main ()
{
        struct record
        {
            // since getMake, getModel and getColor returns a const char *
           // make these const char * too
            const char *make;
            const char *model;
            const char *color;
            int year;
            int mileage;
        };

        struct record r[3];

        const int SIZE = 3;
                       
        //Array of 3 cars
        Car Car_array[SIZE] = { Car("Porsche", "911", "Silver", 2005, 18990),
                                Car("Ford", "Mustang", "Red", 2007, 49842),
                                Car("Chevrolet", "Beretta", "Black", 1989, 90332)};

        // Based on Car_array initialize everything
        for (int i = 0; i < SIZE; i++)
        {
                r[i].make = Car_array[i].getMake();
                r[i].model = Car_array[i].getModel();
                r[i].color = Car_array[i].getColor();
                r[i].year = Car_array[i].getYear();
                r[i].mileage = Car_array[i].getMileage();
        }

        for (int i = 0; i < 3; i++)
        {
        cout << r[i].make << endl
             << r[i].model << endl
             << r[i].color << endl
             << r[i].year << endl
             << r[i].mileage << endl << endl;
        }

        cout << "Writing to file\n\n";
      ofstream out("binaryFile.bin", ios::binary);
      // write three cars
          out.write( (char*)r, sizeof(struct record) * 3);
          out.close();


      // read 3 cars
          cout << "Reading file\n\n";
      ifstream in("binaryFile.bin", ios::binary);
      in.read( (char *)r, sizeof(struct record) * 3);
  return 0;
}

I wrote this code to see how it outputs.(I have included an attachment of my command prompt!


but when I try to open the .bin file it does not show as 1's and 0's and the program still does not read the file for some reason

but when I try to open the .bin file it does not show as 1's and 0's

All files, no matter what they are, are 0's and 1's. To see the 0's and 1's, you need a binary editor. If I write 65 to a file, then open it with "Notepad" or whatever, it's going to show "A", since 'A' is Ascii 65. You need a Hex/Binary editor like Hex Editor Neo to see the 0's and 1's. Are you using one?

and the program still does not read the file for some reason

How do you know whether it reads the file or not? You never display what's been read.

But you definitely have a major error here. Your struct and your class don't match. Your class has character arrays of 40 characters each. Your struct has const char* pointers and you are using sizeof.

The "size" of a const char* is going to be 4 bytes, not 40. It's the size of a pointer and it reserves no space for the data itself. It's a pointer, so if you are planning on writing a 40 byte character array to a binary file, then reading that 40 bytes from the file, I would make sure that sizeof (struct record) is what you expect it to be. If you are expecting it to the size of 120 characters plus two integers (128 bytes), I don't think it's going to be that.

Make your struct record match your Car class. Define the storage length.

and to display whats been wrote into the file would i do this??

// read 3 cars
          cout << "Reading file\n\n";
      ifstream in("binaryFile.dat", ios::binary);
      in.read( (char *)r, sizeof(struct record) * 3);
	  // Based on Car_array initialize everything
        for (int i = 0; i < SIZE; i++)
        {
                r[i].make = Car_array[i].getMake();
                r[i].model = Car_array[i].getModel();
                r[i].color = Car_array[i].getColor();
                r[i].year = Car_array[i].getYear();
                r[i].mileage = Car_array[i].getMileage();
        }

Sorry that I have not been involved in this discussion all day as I have been at work.

The first problem I see is that you don't need that struct record at all. All you need to read and write are the array of Car classes. The code you originally posted can easily be adapted to do that.

Car carsArray[3];

// to write them to a binary file, just do this
ofstream out("dats.dat", ios::binary);
if( out.is_open() )
{
    out.write( (char *)carsArray, sizeof(carsArray));
}

// to read the array is almost the same as writing them
// the only difference is use read() instead of write()

ifstream in("dats.dat", ios::binary);
if( in.is_open() )
{
    in.read( (char *)carsArray, sizeof(carsArray));
}

That's all there is to it.

Your original post almost had it right. Just delete the structure. Note that your original program may not have worked because you failed to close the output file before opening the input file, so the operating system had not flushed the data to the disk before your program tried to read it.

int main () {



	const int SIZE = 3;
    size_t x;			
	//Array of 9 cars
	Car Car_array[SIZE] = { Car("Porsche", "911", "Silver", 2005, 18990), 
							Car("Ford", "Mustang", "Red", 2007, 49842),
							Car("Chevrolet", "Beretta", "Black", 1989, 90332)};


      ofstream out("binaryFile.bin", ios::binary);
      // write three cars
      x = sizeof(Car_array);
	  out.write( (char*)Car_array, x);
      out.close();
      // read 3 cars
      for(int i = 0; i < 3; i++)
          Car_array[i].init();
      ifstream in("binaryFile.bin", ios::binary);
	  in.read( (char*)Car_array, sizeof(Car_array));
      in.close();
  return 0;
}

Edited 6 Years Ago by Ancient Dragon: n/a

Ok, I am not following you here! Do I need to set the array size to 40??

My point was that if you are going to use a record struct, it should match your Car class layout, which it did in post 22, then you changed it in post 24. I was saying you should change it back to what you had in post 22.

But Ancient Dragon is correct. There is no need for a record struct since you already have a Car class.

Sorry that I have not been involved in this discussion all day as I have been at work.

The first problem I see is that you don't need that struct record at all. All you need to read and write are the array of Car classes. The code you originally posted can easily be adapted to do that.

Car carsArray[3];

// to write them to a binary file, just do this
ofstream out("dats.dat", ios::binary);
if( out.is_open() )
{
    out.write( (char *)carsArray, sizeof(carsArray));
}

// to read the array is almost the same as writing them
// the only difference is use read() instead of write()

ifstream in("dats.dat", ios::binary);
if( in.is_open() )
{
    in.read( (char *)carsArray, sizeof(carsArray));
}

That's all there is to it.

Your original post almost had it right. Just delete the structure. Note that your original program may not have worked because you failed to close the output file before opening the input file, so the operating system had not flushed the data to the disk before your program tried to read it.

int main () {



	const int SIZE = 3;
    size_t x;			
	//Array of 9 cars
	Car Car_array[SIZE] = { Car("Porsche", "911", "Silver", 2005, 18990), 
							Car("Ford", "Mustang", "Red", 2007, 49842),
							Car("Chevrolet", "Beretta", "Black", 1989, 90332)};


      ofstream out("binaryFile.bin", ios::binary);
      // write three cars
      x = sizeof(Car_array);
	  out.write( (char*)Car_array, x);
      out.close();
      // read 3 cars
      for(int i = 0; i < 3; i++)
          Car_array[i].init();
      ifstream in("binaryFile.bin", ios::binary);
	  in.read( (char*)Car_array, sizeof(Car_array));
      in.close();
  return 0;
}

Dragon thanks so much for this, its easy to understand and it really helps me! But I have one major question, when I run the program I am getting an error with this line

Car_array[i].init();

Where is the .init coming from and do i need to initialize it somewhere??

This article has been dead for over six months. Start a new discussion instead.