Help with stream processing (newbie hashfile)

This is a discussion on Help with stream processing (newbie hashfile) within the C++ Programming forums, part of the General Programming Boards category; Both the primary and the overflow text files contain fixed-length records. The record structure is: DEL SSN FirstName LastName Pointer ...

  1. #1
    Registered User
    Join Date
    Jan 2007
    Posts
    14

    Help with stream processing (newbie hashfile)

    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;
    }

  2. #2
    System Novice siavoshkc's Avatar
    Join Date
    Jan 2006
    Location
    Tehran
    Posts
    1,231
    Avoid using
    Code:
    #define recordsize 50
    in C++ use
    Code:
     const <type> recordsize 50;
    instead.

    Code:
    hashstream>>ProcessedRecord.DEL;
    Should be
    Code:
     if(hashstream>>ProcessedRecord.DEL)
    to check for errors.
    Learn C++ (C++ Books, C Books, FAQ, Forum Search)
    Code painter latest version on sourceforge DOWNLOAD NOW!
    Download FSB Data Integrity Tester.
    Siavosh K C

  3. #3
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,334
    Your main() needs to go on a serious diet, it's too bloated.

    Eg.
    Code:
    if (choice == 1) {
      doAddRecord();
    }
    All the code for adding records should be in a suitably named function, passed suitable parameters.

    > while (!EOF && overptr != -1 && !duplicate)
    EOF is not the same as eof().
    Also, consult the FAQ about using eof() anyway.

    > if (confirm == 'y' || 'Y' || !duplicate)
    This doesn't do what you think either. It's always true, since it is
    if (confirm == 'y' || 'Y' != 0 || !duplicate)

    The indentation needs work as well, since it seems to randomly move between 4 and 8 spaces.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Discard wrong data from stream
    By mesmer in forum C Programming
    Replies: 7
    Last Post: 11-16-2008, 01:30 AM
  2. Newbie question about string processing
    By prihod in forum C Programming
    Replies: 6
    Last Post: 04-15-2008, 10:14 PM
  3. Closing a stream
    By cunnus88 in forum C++ Programming
    Replies: 8
    Last Post: 02-21-2008, 04:15 PM
  4. Help! About text stream and binary stream
    By Antigloss in forum C Programming
    Replies: 1
    Last Post: 09-01-2005, 08:40 AM
  5. file writing crashes
    By test in forum C Programming
    Replies: 25
    Last Post: 08-13-2002, 08:44 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21