Both the primary and the overflow text files contain fixed-length records. The record structure is: DEL SSN FirstName LastName Pointer
SSN is the primary key of the file.
DEL: an integer, 0: living record slot; 1: deleted/dead record slot; 2: virgin record slot
SSN: a string with 9 digits in the form: 111111111
FirstName: a string of 10 characters
LastName: a string of 20 characters
Pointer: a long integer, it is the byte offset of the next record slot on the overflow chain
Here is what a primary file with only one record would look like
Code:
0 111444550 bob marley -1
2 000000000 * * -1
And this is my current code (edited down a bit for readability). I have colored some of the sticky parts in red. I've also attached my .cpp file.
Any advice would be appreciated. For any questions, please IM gozulin on AIM or gozu at "hotmail" +"." + "com"
Thanks for your time.
Code:
#include <cstdio>
#include <cstdlib>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
#define recordsize 50
bool createFile();
int H(string SSN);
int menu();
int main(void)
{
struct record
{
int DEL;
string FirstName;
string LastName;
string SSN;
long int PTR;
};
int i (0);
int choice (0);
long int hashptr (0);
long int overptr (0);
long int trailptr (0);
bool duplicate (0);
bool OverflowUsed (0);
bool FirstOverflow (1);
char confirm = 'n';
string hashfile = "hashprimary.txt";
string overfile = "hashoverflow.txt";
record blank = {2,"*","*","000000000",-1};
record ProcessedRecord = {0,"*","*","000000000",-1};
record rec = {0,"*","*","000000000",-1};
fstream hashstream;
hashstream.open(hashfile.c_str()); //open the file without creating it
if(!hashstream) //create file if doesn't exist
{
hashstream.close();
cout<<"No hashfile with that name was found. A new file will be created."<<endl;
if (!createFile())
cout<<"Error creating blank files"<<endl;
else
cout<<"Files initialized and created successfully"<<endl;
}
fstream overstream(overfile.c_str()); //create overflow file
do{
int choice = menu();
if (1<=choice && 4>choice)
{
cout<<"please enter the SSN number associated with the record.\n";
cin.ignore();
getline(cin, rec.SSN); //the SSN number is used as a key
}
if (choice == 1) //Adding a record
{
cout<<"Please enter first name: ";
getline(cin, rec.FirstName);
cout<<"Please enter Last name: ";
getline(cin, rec.LastName);
cout<<"Attempting to add record...\n";
}
else if (choice == 2)
{
cout<<"\nAttempting to delete record...\n";
}
else if (choice == 3)
{
cout<<"\n searching for record...\n ";
}
hashptr = H(rec.SSN) * recordsize * 2; //calculate the offset where to store the record based on the H() function (simple mod 10)
hashstream.seekg (hashptr, ios::beg);//goes to beginning of file
hashstream>>ProcessedRecord.DEL;//Reads the variables from the stream and writes them to struct (Problem?)
hashstream.ignore();
hashstream>>ProcessedRecord.SSN;
for (i=0;i<31;i++)
hashstream.ignore();//ignores first and last name values
cout<<"DEL is: "<<ProcessedRecord.DEL<<endl;
hashstream>>ProcessedRecord.PTR;
cout<<"PTR is: "<<ProcessedRecord.PTR<<endl;[/color]
if (ProcessedRecord.SSN == rec.SSN)//Duplicate record detected
duplicate = true;
if (ProcessedRecord.DEL == 0 && !duplicate)//live record already present at that location
{
hashptr = hashptr + recordsize;//jumps to the second record in the bucket and repeats
hashstream.seekg (hashptr, ios::cur);
hashstream>>ProcessedRecord.DEL;
hashstream.ignore();
hashstream>>ProcessedRecord.SSN;
for (i=0;i<31;i++)
hashstream.ignore();
cout<<"DEL is: "<<ProcessedRecord.DEL<<endl;
hashstream>>ProcessedRecord.PTR;
cout<<"PTR is: "<<ProcessedRecord.PTR<<endl;
duplicate = (ProcessedRecord.SSN == rec.SSN);
overptr = ProcessedRecord.PTR;
if ((ProcessedRecord.DEL == 0 && !duplicate))//live record found in 2nd (and last) bucket, time for some overflow file action!
{
OverflowUsed = true;
while (!EOF && overptr != -1 && !duplicate)//keep seeking any records on the overflow chain (a -1 PTR means the chain is over)
{
overstream.seekg(overptr, ios::beg);
overstream>>ProcessedRecord.DEL;
overstream.ignore();
overstream>>ProcessedRecord.SSN;
for (i=0;i<31;i++)
overstream.ignore();
cout<<"DEL is: "<<ProcessedRecord.DEL<<endl;
overstream>>ProcessedRecord.PTR;//Points to the next record on overflow chain
cout<<"PTR is: "<<ProcessedRecord.PTR<<endl;
overptr = ProcessedRecord.PTR;//
trailptr = overstream.tellg();
duplicate = ProcessedRecord.SSN == rec.SSN;//live record found with unique SSN
}
if (!duplicate && choice == 1)//This adds a new record at the end of the overflow file
{
overstream.seekp(0, ios::end);
overptr = overstream.tellp();
overstream<<"0 "<<rec.SSN<<" "<<rec.FirstName;
for(i=(rec.FirstName).length(); i<=11; i++)
overstream<<' ';
overstream<<rec.LastName;
for(i= ((rec.LastName).length()); i<=21; i++)
overstream<<' ';
overstream<<rec.PTR<<endl;
hashstream.seekg(-6,ios::cur);//jumps to PTR position in the last record accessed
hashstream<<overptr;//overwrites the PTR integer to the offset of the record just written to the overflow file.
overstream.seekp(trailptr, ios::beg);
overstream.seekp(-6,ios::cur);//overwrites the PTR integer to the offset of the next record in the chain
hashstream<<overptr;
cout<<"The record was inserted successfully in the overflow file"<<endl;
}
}
}
if (duplicate)//record found with the SSN key
{
cout<<"This following record exists with that SSN: "<<endl;
cout<<"SSN: "<<ProcessedRecord.SSN<<endl;
cout<<"FirstName: "<<ProcessedRecord.FirstName<<endl;
cout<<"LastName: "<<ProcessedRecord.LastName<<endl<<endl;
}
if (choice == 1)
{
if (duplicate)//gives the user the option to overwrite the old record
{
cout<<"Overwrite the record? type 'y' for YES and 'n' for NO: ";
cin>>confirm;
}
if (confirm == 'y' || 'Y' || !duplicate)
{
hashstream<<"0 "<<rec.SSN<<" "<<rec.FirstName;
for(i=(rec.FirstName).length(); i<=11; i++)
hashstream<<' ';
hashstream<<rec.LastName;
for(i=(rec.LastName).length(); i<=21; i++)
hashstream<<' ';
hashstream<<rec.PTR<<endl;
cout<<"The record was inserted successfully in the primary file.\n\n";
}
else
cout<<"You did not press the 'y' key, operation cancelled. No changes were made.\n\n";
}
else if (choice == 2)//marks the record as deletable by overwriting the DEL integer with 1
{
if (OverflowUsed)
{
overstream.seekp(trailptr-recordsize);
overstream<<1;
OverflowUsed = 0;
}
else
{
hashstream.seekp(hashptr-recordsize);
hashstream<<1;
}
cout<<"\nThe record has been successfully deleted.\n\n";
}
else if (choice != 3)
cout<<"You did not select a valid option number. Please try again.\n\n";
}while(choice != 4);
return 0;}
int H(string SSN)
{
return (atol(SSN.c_str()) % 10);
}
int menu()
{
int choice (3);
cout<<"press 1 to add a record\n";
cout<<"press 2 to delete a record\n";
cout<<"press 3 to find a record\n";
cout<<"press 4 to exit the program\n";
cout<<"User selection: ";
cin>>choice;
return choice;
}
bool createFile()
{
long int Pointer (-1);
ofstream hashstream;
hashstream.open("hashprimary.txt");
for(int i=0;i<20;i++)
hashstream<<2<<" 000000000 * * "<<Pointer<<"\n";
hashstream.close();
ofstream overstream;
overstream.open("hashoverflow.txt");
overstream.close();
return true;
}