So my Data Structures class has finished the book we were using, but we still have a week of school left. My instructor has started going over binary files... only problem is I wasn't there when he went over it.

My assignment is to open a binary file, save the contents to a dynamic array, and output the contents to the screen. I'm getting close (I think) but when I output the array, it's not outputting in clear text. What am I doing wrong?

Here's what I have so far... but I'm really confused right now. This is the accumulation of a lot of copy/paste.

// emprecs.cpp

#include <iostream>
#include <fstream>
using namespace std;
 
const int SIZE = 12;
struct employee {
	char fname[SIZE];
	char lname[SIZE];
	float wage;
	float hours;
	void print() ;
};
 // readTxt() reads the records in input.txt, stores them in ary,
 //  and returns the number of records read
int readTxt(employee ary[]);
 // writeBin() writes the array of employee records to output.bin
void writeBin(employee ary[], int n);

void readFile(employee ray[]);

int main()
{
	employee payroll[SIZE];
	
	int count = readTxt(payroll);  // count = number of records in file
	if ( count > 0 ) {
		writeBin(payroll, count);
	} // endif

	readFile(payroll) ;
	cout << endl;
	cout.write(reinterpret_cast<char *>(payroll), sizeof(employee) * count);

	cout << "\n\n-- Program Complete --\n\n" ;

	return 0;
}

int readTxt(employee ary[])
{
	char temp[SIZE];
	int k = 0;
	ifstream inFil( "input.txt" );

	if ( inFil.is_open() ) {
		while ( !inFil.eof() ) {
			inFil.getline(ary[k].fname, SIZE, ',');
			inFil.getline(ary[k].lname, SIZE, ',');
			inFil.getline(temp, SIZE, ',');
			ary[k].wage = static_cast<float>(atof(temp));
			inFil.getline(temp, SIZE);
			ary[k].hours = static_cast<float>(atof(temp));
			k++;
		} // endwhile
		for ( int j = 0; j < k-1; j++ )
			cout << ary[j].fname << ',' << ary[j].lname << ',' 
			     << ary[j].wage << ',' << ary[j].hours << endl;
		inFil.close();
	}
	else {
		cout << "\n\nUnable to open input file. Please verify filename and permissions.\n\n";
	} // endif
	return k;
}

void writeBin(employee ary[], int n)
{
	ofstream binOut("output.bin", ios::binary);

	if ( binOut.is_open() ) {
		binOut.write(reinterpret_cast<char *>(&n), sizeof(int));
		binOut.write(reinterpret_cast<char *>(ary), sizeof(employee) * n);
		binOut.close();
	}
	else {
		cout << "\nCannot open output file - verify filename and permissions\n";
	} // endif
}

void readFile(employee ray[])
{
    ifstream fin("output.bin", ios::in | ios::binary);
    if ( fin.is_open() ) {
        fin.read( reinterpret_cast <char *>(ray), sizeof(employee) * SIZE);
        cout << "Number of bytes read is: " << fin.gcount();
        fin.close();
    }
    else
        cout << "File not opened" << endl;
} // endif

/*
Example Output:
Martha, Stewart,2.4,40
Jim, Jailson,3.4,30
George, Jefferson,5.9,45
Number of bytes read is: 132
♦   Martha cÉδ%  Stewart FB ÜÖ↓@   BJim ☻   ¶δ%  Jailson íRcÜÖY@  ≡AGeorge  `C☼
 Jefferson  ═╠╝@  4B δ% ☻╡ScY┼☼         `C☼

-- Program Complete --

Press any key to continue . . .
*/

/*
 */

Why do your write the number of records to the binary file, but not read it it back? Instead, you're reading in the full (potential)size of the array's worth of data, which will include that one int at the front of it, putting everything else out of sync.

This line

cout.write(reinterpret_cast<char *>(payroll), sizeof(employee) * count);

Looks odd - do you really want to put the memory image to screen? cout is a text based stream.

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