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

Dani AI

Generated

— the output you showed comes from simple overwrites at the hashed slot: when two keys produce the same index the second write replaces the first. was right to push you toward random-access positioning, but you also need a collision-resolution strategy (linear probing or chaining). Pick one table size (a named constant) and use it consistently for both hashing and probing so offsets map to the real number of records in the file.

A practical approach (linear probing) in plain steps:

  1. Define TABLE_SIZE and RECORD_SIZE once.
  2. When inserting: compute start = hash(id) % TABLE_SIZE. Probe successive slots (start, start+1, ...) wrapping with modulo TABLE_SIZE. For each slot seek and read the slot; if empty or same id, seek back and write the record; stop. If you loop TABLE_SIZE times, report "table full".
  3. When looking up a key: start at the same hashed index and probe the same way until you find the id or hit an empty slot (then it is not present).
  4. Open the binary file for random access using a single std::fstream with ios::binary | ios::in | ios::out (or close/reopen appropriately). Clear EOF flags if you switch between read/write and always use seekg/seekp to reposition.

Troubleshooting tips: make the "empty" sentinel explicit and consistent, detect a full table to avoid infinite loops, and confirm your record's byte layout (padding/alignment) so offsets are exact. If you prefer chaining, store small lists at slots (more complex but avoids probing). For background on the probing idea see Linear probing and for correct seek/read/write semantics check the fstream docs on repositioning at cppreference: basic_fstream.

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.