A Complete Guide to Programming in C++ part 70 ppsx

10 250 0
A Complete Guide to Programming in C++ part 70 ppsx

Đang tải... (xem toàn văn)

Thông tin tài liệu

SOLUTIONS ■ 669 void IndexFile::display() throw(ReadError) { IndexEntry entry; index.seekg(0L); if(!index) throw ReadError("IndexFile: Setting the get pointer"); cout << endl << "The Index: " << endl; while( true) { if( !entry.read(index)) break; entry.display(); } if( !index.eof()) throw ReadError(name); index.clear(); } long IndexFile::search(long k) throw(ReadError) { IndexEntry entry; long key; long mid, begin = 0, end; // Number of file records. int size = entry.recordSize(); // Length of an index // entry. index.clear(); index.seekg(0L, ios::end); end = index.tellg() / size; if(!index) throw ReadError(name); if( end == 0) return -1; end -= 1; // Position of the last entry while( begin < end ) { mid = (begin + end +1)/2 ; entry.read_at(index, mid*size); if(!index) throw ReadError(name); key = entry.getKey(); if( k < key) end = mid - 1; else begin = mid; } 670 ■ CHAPTER 29 MORE ABOUT FILES entry.read_at(index, begin * size); if(!index) throw ReadError(name); if( k == entry.getKey() ) // Key found? return begin * size; else return -1; } void IndexFile::insert(long k, long n) throw(ReadError, WriteError) { IndexEntry entry; int size = entry.recordSize(); // Length of an index // entry. index.clear(); index.seekg(0, ios::end); long nr = index.tellg(); // Get file length // 0, if file is empty. if(!index) throw ReadError(name); nr -= size; // Last entry. bool found = false; while( nr >= 0 && !found ) // Search position { // to insert if(!entry.read_at(index, nr)) throw ReadError(name); if( k < entry.getKey()) // To shift. { entry.write_at(index, nr + size); nr -= size; } else { found = true; } } entry.setKey(k); entry.setPos(n); // Insert entry.write_at(index, nr + size); if(!index) throw WriteError(name); } SOLUTIONS ■ 671 void IndexFile::retrieve( IndexEntry& entry, long pos) throw(ReadError) { index.clear(); if(!entry.read_at(index, pos)) throw ReadError(name); } // // Implementing the methods of class IndexFileSystem. bool IndexFileSystem::insert( Account& acc) throw(ReadError, WriteError) { if(search(acc.getNr()) == -1) // No multiple entries. { long pos = append(acc); // Add to primary file. IndexFile::insert(acc.getNr(), pos); // Add to Index return true; } else return false; } Account* IndexFileSystem::retrieve(long key ) { // Get the record address from the index: long pos = search(key); // Byte offset of // index entry. if( pos == -1 ) // Account number doesn't exist. return NULL; else // Account number does exist: { IndexEntry entry; // To read the index eintry IndexFile::retrieve( entry, pos); // Get from primary file: return( AccFile::retrieve( entry.getPos() )); } } // // index_t.cpp : Testing the index file // #include <iostream> #include <string> using namespace std; #include "index.h" #include "account.h" 672 ■ CHAPTER 29 MORE ABOUT FILES int main() { try { IndexFileSystem database("AccountTest"); Account acc1( "Vivi", 490UL, 12340.57); database.insert( acc1 ); SavAcc acc2( "Ulla", 590UL, 4321.19, 2.5); database.insert( acc2 ); DepAcc acc3( "Jeany", 390UL, 12340.20, 10000.0, 12.9); database.insert( acc3 ); database.IndexFile::display(); cin.get(); database.AccFile::display(); unsigned long key; cout << "Key? "; cin >> key; if(database.search(key) != -1) cout << "Key " << key << " found" << endl; else cout << "Key " << key << " not found" << endl; Account* pAcc = database.retrieve(key); if( pAcc != NULL ) { pAcc->display(); delete pAcc; pAcc = NULL; } else cout << "Retrieving failed" << endl; } catch(OpenError& err) { cerr << "Error on opening the file:" << err.getName() << endl; exit(1); } catch(WriteError& err) { cerr << "Error on writing into the file: " << err.getName() << endl; exit(1); } SOLUTIONS ■ 673 catch(ReadError& err) { cerr << "Error on reading from the file: " << err.getName() << endl; exit(1); } catch( ) { cerr << " Unhandled Exception" << endl; exit(1); } return 0; } Exercise 2 // // exceptio.h : Error classes for file processing // // As seen previously in this chapter. // // hashFile.h // Defines the classes // HashEntry representing a record in a hash file and // HashFile representing a hash file. // #ifndef _HASH_H_ #define _HASH_H_ #include <fstream> #include <iostream> #include <iomanip> #include <string> #include <string.h> using namespace std; #include "exceptio.h" class HashEntry { private: unsigned long nr; char name[30]; 674 ■ CHAPTER 29 MORE ABOUT FILES public: HashEntry(unsigned long n = 0L, const string& s = "") { nr = n; strncpy(name, s.c_str(), 29); name[30]='\0'; } long getNr() const { return nr; } void setNr(unsigned long n){ nr = n; } string getName() const { return name; } void setName(const string& s) { strncpy(name, s.c_str(), 29); name[30]='\0'; } int getSize() const { return(sizeof(long) + sizeof(name)); } fstream& write(fstream& fs); fstream& read(fstream& fs); fstream& write_at(fstream& fs, unsigned long pos); fstream& read_at(fstream& fs, unsigned long pos); virtual void display() { cout << fixed << setprecision(2) << " \n" << "Client number: " << nr << endl << "Client: " << name << endl << " \n" << endl; cin.get(); } }; class HashFile { private: fstream f; string name; // Filename unsigned long b; // Size of address space protected: unsigned long hash_func(unsigned long key) { return key%b; } public: HashFile(const string s, unsigned long n ) throw(OpenError); SOLUTIONS ■ 675 void insert( HashEntry& rec) throw( ReadError, WriteError ); HashEntry& retrieve( unsigned long key ) throw( ReadError ); void display(); }; #endif // // hashFile.cpp : Methods of classes HashEntry and HashFile // #include "hashFile.h" fstream& HashEntry::write(fstream& f) { f.write((char*)&nr, sizeof(nr) ); f.write( name, sizeof(name) ); return f; } fstream& HashEntry::read(fstream& f) { f.read((char*)&nr, sizeof(nr) ); f.read( name, sizeof(name)); return f; } fstream& HashEntry::write_at(fstream& f, unsigned long pos) { f.seekp(pos); f.write((char*)&nr, sizeof(nr) ); f.write( name, sizeof(name) ); return f; } fstream& HashEntry::read_at(fstream& f, unsigned long pos) { f.seekg(pos); f.read((char*)&nr, sizeof(nr) ); f.read( name, sizeof(name)); return f; } 676 ■ CHAPTER 29 MORE ABOUT FILES HashFile::HashFile(const string file, unsigned long n) throw(OpenError) { ios::openmode mode = ios::in | ios::out | ios::binary; f.open(file.c_str(), mode); // Open file if it // already exists. if(!f) // If file doesn't exist: { f.clear(); mode |= ios::trunc; f.open(file.c_str(), mode); if(!f) throw OpenError(name); } name = file; b = n; HashEntry rec(0L, ""); f.seekp(0L); for( unsigned long i=0; i < b; i++) // Initialize { // the address space rec.write(f); if(!f) throw WriteError(name); } } void HashFile::insert( HashEntry& rec) throw( ReadError, WriteError) { HashEntry temp; int size = temp.getSize(); // Hash-Wert: unsigned long pos = hash_func(rec.getNr()); temp.read_at(f, pos*size); // Read a slot. if(!f) throw ReadError(name); else { if(temp.getNr() == 0L) // Slot free? rec.write_at(f, pos*size); // Yes => Add // to the file. else // No => Search for { // a free slot. bool found = false; unsigned long p = (pos*size + size)%(b*size); SOLUTIONS ■ 677 while( !found && p!= pos*size ) { temp.read_at(f, p); if(!f) throw ReadError(name); else if(temp.getNr() == 0L) // Free slot found = true; // found. else // Proceed to the next slot: p = (p + size)%(b*size); } if( p == pos*size ) // Address space full. throw WriteError(name); if ( found == true ) // Add to file. rec.write_at(f,p); } if(!f) throw WriteError(name); } } HashEntry& HashFile::retrieve( unsigned long key ) throw(ReadError) { static HashEntry temp; int size = temp.getSize(); unsigned long pos = hash_func(key); // Hash value. temp.read_at(f, pos*size); // Read a slot. if(!f) throw ReadError(name); if(temp.getNr() == key) // Found? return temp; // Yes => finish else // No => search { unsigned long p = (pos*size + size)%(b*size); while( p!= pos *size ) { temp.read_at(f, p); if(!f) throw ReadError(name); 678 ■ CHAPTER 29 MORE ABOUT FILES else if(temp.getNr() == key) // Record found. return temp; else p = (p + size)%(b*size); // Proceed to the } // next slot. temp.setNr(0L); temp.setName(""); // Key doesn't // exist. return temp; } } void HashFile::display() { HashEntry temp; f.seekg(0L); for(unsigned int i = 0; i < b; i++) { temp.read(f); if(!f) throw ReadError(name); temp.display(); } f.clear(); } // // hash_t.cpp : Tests hash files // #include <iostream> #include <string> #include "hashFile.h" using namespace std; int main() { try { HashFile hash("Client.fle", 7); // Address space // of length 7 cout << "\nInsert: " << endl; HashEntry kde( 3L, "Vivi"); hash.insert( kde ); . } fstream& write(fstream& fs); fstream& read(fstream& fs); fstream& write_at(fstream& fs, unsigned long pos); fstream& read_at(fstream& fs, unsigned long pos); virtual. database("AccountTest"); Account acc1( "Vivi", 490UL, 12340.57); database.insert( acc1 ); SavAcc acc2( "Ulla", 590UL, 4321.19, 2.5); database.insert( acc2 ); DepAcc acc3(. hashFile.h // Defines the classes // HashEntry representing a record in a hash file and // HashFile representing a hash file. // #ifndef _HASH_H_ #define _HASH_H_ #include <fstream> #include <iostream> #include

Ngày đăng: 06/07/2014, 17:21

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan