Ok what i'm trying to do in this program is first create an empty binary file of size 31 records. Records includes studid & gpa. and then I insert valid record into the binary file with h(k) = key% 29..and then read this binary file sequentially and write the records and their position into output file.....

sample input file
31 2.34
62 1.55
60
3.25
333 3.33
38 3.90
-1 //read upto -1

studBinaryFile.h

#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

const int MIN_ID = 11;
const int MAX_ID = 99;
const float MIN_GPA = 0.00;
const float MAX_GPA = 4.00;

class StudBinaryFile
{
 public:

 void setId(int idVal);
 
 void setGpa(float gpaVal);

 void ReadRd(int i,ifstream& inFile);

 bool validRd();
 
 void writeBinary(StudBinaryFile rd, ofstream& outFile);

 void writeInvalidRd(ofstream& outFile2);

 void readBinary(StudBinaryFile rd, ifstream& inFile, ofstream&    outFile2);
 
 void printData(int count, const StudBinaryFile& record, ofstream&  outFile2);
 
private:
   int id;
   float gpa;
};
studBinaryFile.cxx

#include "studBinaryFile.h"

void StudBinaryFile::setId(int idVal)
{
	id = idVal;
}

void StudBinaryFile::setGpa(float gpaVal)
{
	gpa = gpaVal;
}

void StudBinaryFile::ReadRd(int i, ifstream& inFile)
{
	id = i;
	inFile >> gpa;
}


bool StudBinaryFile::validRd() 
{
	 return ((id >= MIN_ID)&&
                (id <= MAX_ID)&&
                (gpa >= MIN_GPA)&&
                (gpa <= MAX_GPA));

}

void StudBinaryFile::writeBinary(StudBinaryFile rd, ofstream& outFile)
{
	outFile.seekp((id % 29) * sizeof(rd));
	{outFile.write(reinterpret_cast<const char *> (&rd), sizeof(rd));}
}

void StudBinaryFile::readBinary(StudBinaryFile rd, ifstream& inFile, ofstream& outFile2)
{
	int count = 0;
	inFile.read(reinterpret_cast<char *> (&rd), sizeof(StudBinaryFile));
	while(inFile)
	{
		if (id != 0)
		{
			printData(count, rd, outFile2);
			count++;
		}
		inFile.read(reinterpret_cast<char *> (&rd), sizeof(StudBinaryFile));		
	}
} 

void StudBinaryFile::writeInvalidRd(ofstream& outFile2)
{
	outFile2 << id << setw(12) << gpa << endl;
}

void StudBinaryFile::printData(int count, const StudBinaryFile& record, ofstream& outFile2)
{
	if(record.id != 0)
		outFile2 << count << ".)  "  << record.id << setw(12) << record.gpa << endl;
	else
		outFile2 << count << ".)  " << "Empty record" << endl;

	count++;
}
run.cxx

#include "studBinaryFile.h"
int main()
{
	ifstream inFile, inFile2;
	ofstream outFile, outFile2;
	inFile.open("in.data");
	outFile.open("binrecords.bin",ios::out | ios::binary);

	outFile2.open("out.data");

	StudBinaryFile blankRd;
	for (int i = 1; i<=31; i++)
	{
		blankRd.setId(0);
		blankRd.setGpa(0.0);
		outFile.write(reinterpret_cast<const char *> (&blankRd), sizeof(blankRd));
	}

	StudBinaryFile rd;
	outFile.seekp(0L,ios::beg);
	int spliter;
	outFile2 << "*< Invalid Records Report >*" << endl;
	
	inFile >> spliter;
	while(spliter != -1)
	{
		rd.ReadRd(spliter,inFile);
		if(rd.validRd())
		{
			
			rd.writeBinary(rd, outFile);
		}
		else
			{rd.writeInvalidRd(outFile2);}
		inFile >> spliter;
	}
	outFile2 << "<* end >*" << endl << endl;
	inFile.close();
	outFile.close();

	outFile2 << "Reading random file sequentially" << endl;
	inFile.open("binrecords.bin", ios::in | ios::binary);
	rd.readBinary(rd, inFile, outFile2);

	inFile.close();
	return 0;
}

This is the output im getting

*< Invalid Records Report >*
333        3.33
<* end >*

Reading random file sequentially
0.)  Empty record
1.)  Empty record
2.)  60        3.25
3.)  Empty record
4.)  62        1.55
5.)  Empty record
6.)  Empty record
7.)  Empty record
8.)  Empty record
9.)  38         3.9
10.)  Empty record
11.)  Empty record
12.)  Empty record
13.)  Empty record
14.)  Empty record
15.)  Empty record
16.)  Empty record
17.)  Empty record
18.)  Empty record
19.)  Empty record
20.)  Empty record
21.)  Empty record
22.)  Empty record
23.)  Empty record
24.)  Empty record
25.)  Empty record
26.)  Empty record
27.)  Empty record
28.)  Empty record
29.)  Empty record
30.)  Empty record

This is the output i want

*< Invalid Records Report >*
333        3.33
<* end >*

Reading random file sequentially
0.)  Empty record
1.)  Empty record
2.)  31        2.34
3.)  60        3.25
4.)  62        1.55
5.)  Empty record
6.)  Empty record
7.)  Empty record
8.)  Empty record
9.)  38         3.9
10.)  Empty record
11.)  Empty record
12.)  Empty record
13.)  Empty record
14.)  Empty record
15.)  Empty record
16.)  Empty record
17.)  Empty record
18.)  Empty record
19.)  Empty record
20.)  Empty record
21.)  Empty record
22.)  Empty record
23.)  Empty record
24.)  Empty record
25.)  Empty record
26.)  Empty record
27.)  Empty record
28.)  Empty record
29.)  Empty record
30.)  Empty record

This program works fine except that its overriding some of the record because of collision problem ..someone please help me here

Recommended Answers

All 5 Replies

you have a few problems with that class. I just put all the files into one *.cpp file because I was too lazy to use separate files as you posted them.

The main problem was in the readBinary() function. Using the sample data you posted I got the same output that you expected.

#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

const int MIN_ID = 11;
const int MAX_ID = 99;
const float MIN_GPA = 0.00;
const float MAX_GPA = 4.00;

class StudBinaryFile
{
 public:
     StudBinaryFile() { id = 0; gpa = 0; }

 void setId(int idVal);
 
 void setGpa(float gpaVal);

 void ReadRd(int i,ifstream& inFile);

 bool validRd();
 
 void writeBinary(ofstream& outFile);

 void writeInvalidRd(ofstream& outFile2);

 void readBinary(ifstream& inFile, ofstream&    outFile2);
 
 void printData(int count, ofstream&  outFile2);
 
private:
   int id;
   float gpa;
};


void StudBinaryFile::setId(int idVal)
{
	id = idVal;
}

void StudBinaryFile::setGpa(float gpaVal)
{
	gpa = gpaVal;
}

void StudBinaryFile::ReadRd(int i, ifstream& inFile)
{
	id = i;
	inFile >> gpa;
}


bool StudBinaryFile::validRd() 
{
	 return ((id >= MIN_ID)&&
                (id <= MAX_ID)&&
                (gpa >= MIN_GPA)&&
                (gpa <= MAX_GPA));

}

void StudBinaryFile::writeBinary(ofstream& outFile)
{
	outFile.seekp((id % 29) * sizeof(StudBinaryFile));
	{outFile.write(reinterpret_cast<const char *> (this), sizeof(StudBinaryFile));}
}

void StudBinaryFile::readBinary(ifstream& inFile, ofstream& outFile2)
{
	int count = 0;
	inFile.read(reinterpret_cast<char *> (this), sizeof(StudBinaryFile));
	while(inFile)
	{
	    printData(count,  outFile2);
		count++;
		inFile.read(reinterpret_cast<char *> (this), sizeof(StudBinaryFile));		
	}
} 

void StudBinaryFile::writeInvalidRd(ofstream& outFile2)
{
	outFile2 << id << setw(12) << gpa << endl;
}

void StudBinaryFile::printData(int count,ofstream& outFile2)
{
	if(id != 0)
		outFile2 << count << ".)  "  << id << setw(12) << gpa << endl;
	else
		outFile2 << count << ".)  " << "Empty record" << endl;

	count++;
}

int main()
{
	ifstream inFile, inFile2;
	ofstream outFile, outFile2;
	inFile.open("in.data");
	outFile.open("binrecords.bin",ios::out | ios::binary);

	outFile2.open("out.data");

	StudBinaryFile blankRd;
	for (int i = 1; i<=31; i++)
	{
//		blankRd.setId(0);
//		blankRd.setGpa(0.0);
		outFile.write(reinterpret_cast<const char *> (&blankRd), sizeof(blankRd));
	}
    outFile.flush();

	StudBinaryFile rd;
	outFile.seekp(0L,ios::beg);
	int spliter;
	outFile2 << "*< Invalid Records Report >*" << endl;
	
	inFile >> spliter;
	while(spliter != -1)
	{
		rd.ReadRd(spliter,inFile);
		if(rd.validRd())
		{
			
			rd.writeBinary(outFile);
		}
		else
			{rd.writeInvalidRd(outFile2);}
		inFile >> spliter;
	}
	outFile2 << "<* end >*" << endl << endl;
	inFile.close();
	outFile.close();

	outFile2 << "Reading random file sequentially" << endl;
	inFile.open("binrecords.bin", ios::in | ios::binary);
	rd.readBinary(inFile, outFile2);

	inFile.close();
	return 0;
}

Thank you so much for your help. I have another question...lets say in same program i have the input file
31 2.34
62 1.55
60 3.25
333 3.33
38 3.90
-1 // -1 seperates two kind of inputs. Next two input are for random access
62
38

In the same program how can I read that binary file randomely. So basically i want to read the next input after -1 from text file and compare the record to record in binary file and then if they match print it in outfile

This is the output I need
*< Invalid Records Report >*
333        3.33
<* end >*

Reading random file sequentially
0.)  Empty record
1.)  Empty record
2.)  31        2.34
3.)  61        3.25
4.)  62        1.55
5.)  Empty record
6.)  Empty record
7.)  Empty record
8.)  Empty record
9.)  38         3.9
10.)  Empty record
11.)  Empty record
12.)  Empty record
13.)  Empty record
14.)  Empty record
15.)  Empty record
16.)  Empty record
17.)  Empty record
18.)  Empty record
19.)  Empty record
20.)  Empty record
21.)  Empty record
22.)  Empty record
23.)  Empty record
24.)  Empty record
25.)  Empty record
26.)  Empty record
27.)  Empty record
28.)  Empty record
29.)  Empty record
30.)  Empty record

Reading Random Randomly
7.) 62           1.55
9.)  38          3.90

>>how can I read that binary file randomely
Can't do it. Text files can only be read sequentially because of the variable-length records. And that input file (in.data) is a text file, not a binary file.

NO what I mean is how can i read that file "binrecords.bin" randomely ?

If you don't care which record is being read, then just do seekp() to the desired record number and read it.

Otherwise, if you want a specific record then you need to sort the file so that it is in sequential order. Then you could do a binary search algorithm to find the specific record. Since the file is quite small, just read the entire file into an array, discarding the unused records. Then sort the array, and search it. But that is a lot of work for such a small file.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.