1. Trang chủ
  2. » Công Nghệ Thông Tin

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

10 252 0
Tài liệu đã được kiểm tra trùng lặp

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 95,51 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

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