Lecture 9 Classes and Data Abstraction and File
Lecture 9 Classes and Data Abstraction and File Processing 1
14. 1 n Storage of data q q Arrays, variables are temporary Files are permanent n n Introduction Magnetic disk, optical disk, tapes In this chapter q q q Create, update, process files Sequential and random access Formatted and raw processing 2
14. 2 n The Data Hierarchy From smallest to largest q Bit (binary digit) n n 1 or 0 Everything in computer ultimately represented as bits Cumbersome for humans to use Character set q q q Digits, letters, symbols used to represent data Every character represented by 1's and 0's Byte: 8 bits n n Can store a character (char) Also Unicode for large character sets (wchar_t) 3
14. 2 n The Data Hierarchy From smallest to largest (continued) q Field: group of characters with some meaning n q Record: group of related fields n struct or class in C++ n In payroll system, could be name, SS#, address, wage Each field associated with same employee Record key: field used to uniquely identify record n n q File: group of related records n n q Your name Payroll for entire company Sequential file: records stored by key Database: group of related files n Payroll, accounts-receivable, inventory… 4
14. 3 n Files and Streams C++ views file as sequence of bytes q Ends with end-of-file marker 0 1 2 3 4 5 6 7 8 9 . . . n n-1 end-of-file marker When file opened q q Object created, stream associated with it cin, cout, etc. created when <iostream> included n Communication between program and file/device 5
14. 3 n Files and Streams To perform file processing q Include <iostream> and <fstream> q Class templates n n n q basic_ifstream (input) basic_ofstream (output) basic_fstream (I/O) typedefs for specializations that allow char I/O n n n ifstream (char input) ofstream (char output) fstream (char I/O) 6
14. 3 n Files and Streams Opening files q q Create objects from template Derive from stream classes n n Can use stream methods from Ch. 12 put, get, peek, etc. basic_ios basic_istream basic_ifstream basic_ostream basic_iostream basic_ofstream basic_fstream 7
14. 4 Creating a Sequential-Access File n C++ imposes no structure on file q n Concept of "record" must be implemented by programmer To open file, create objects q q Creates "line of communication" from object to file Classes n n n q ifstream (input only) ofstream (output only) fstream (I/O) Constructors take file name and file-open mode ofstream out. Client. File( "filename", file. Open. Mode ); q To attach a file later ofstream out. Client. File; out. Client. File. open( "filename", file. Open. Mode); 8
14. 4 Creating a Sequential. Access File n File-open modes q ofstream opened for output by default n n ofstream out. Client. File( "clients. dat", ios: : out ); ofstream out. Client. File( "clients. dat"); 9
14. 4 Creating a Sequential-Access File n Operations q Overloaded operator! n n !out. Client. File Returns nonzero (true) if badbit or failbit set q q Opened non-existent file for reading, wrong permissions Overloaded operator void* n n Converts stream object to pointer 0 when failbit or badbit set, otherwise nonzero q n failbit set when EOF found while ( cin >> my. Variable ) q Implicitly converts cin to pointer q Loops until EOF 10
14. 4 Creating a Sequential. Access File n Operations q Writing to file (just like cout) n q out. Client. File << my. Variable Closing file n out. Client. File. close() n Automatically closed when destructor called 11
1 // Fig. 14. 4: fig 14_04. cpp 2 // Create a sequential file. 3 #include <iostream> 4 using std: : cout; 5 using std: : cin; 6 using std: : ios; 7 using std: : cerr; 8 using std: : endl; 9 10 #include <fstream> 11 using std: : ofstream; 12 13 #include <cstdlib> // exit prototype 14 15 int main() { 16 // ofstream constructor opens file 17 ofstream out. Client. File( "clients. dat", ios: : out ); 18 fig 14_04. cp p (1 of 2) 12
19 // exit program if unable to create file 20 if ( !out. Client. File ) { // overloaded ! operator 21 cerr << "File could not be opened" << endl; 22 exit( 1 ); 23 } // end if 24 25 cout << "Enter the account, name, and balance. " << endl 26 << "Enter end-of-file to end input. n? "; 27 28 int account; 29 char name[ 30 ]; 30 double balance; 31 // read account, name and balance from cin, then place in file 32 while ( cin >> account >> name >> balance ) { 33 out. Client. File << account << ' ' << name << ' ' << balance 34 << endl; 35 cout << "? "; 36 } // end while 37 return 0; // ofstream destructor closes file 38 } // end main fig 14_04. cp p (2 of 2) 13
fig 14_04. cpp output (1 of 1) Enter ? 100 ? 200 ? 300 ? 400 ? 500 ? ^Z the account, name, and balance. end-of-file to end input. Jones 24. 98 Doe 345. 67 White 0. 00 Stone -42. 16 Rich 224. 62 14
14. 5 Reading Data from a Sequential-Access File n Reading files q ifstream in. Client. File( "filename", ios: : in ); q Overloaded ! n q !in. Client. File tests if file was opened properly operator void* converts to pointer n n while (in. Client. File >> my. Variable) Stops when EOF found (gets value 0) 15
14. 5 Reading Data from a Sequential-Access File n File position pointers q q Number of next byte to read/write Functions to reposition pointer n seekg (seek get for istream class) seekp (seek put for ostream class) n Classes have "get" and "put" pointers n q seekg and seekp take offset and direction n n Offset: number of bytes relative to direction Direction (ios: : beg default) q q q ios: : beg - relative to beginning of stream ios: : cur - relative to current position ios: : end - relative to end 16
14. 5 Reading Data from a Sequential-Access File n Examples q file. Object. seekg(0) n q file. Object. seekg(n) n q Goes y bytes back from end file. Object. seekg(0, ios: : cur) n q Goes n bytes forward file. Object. seekg(y, ios: : end) n q Goes to nth byte from beginning file. Object. seekg(n, ios: : cur) n q Goes to front of file (location 0) because ios: : beg is default Goes to last byte seekp similar 17
14. 5 Reading Data from a Sequential-Access File n To find pointer location q q n tellg and tellp location = file. Object. tellg() Upcoming example q q Credit manager program List accounts with zero balance, credit, and debit 18
52 // process user's request 53 while ( request != END ) { 54 55 switch ( request ) { 56 57 case ZERO_BALANCE: 58 cout << "n. Accounts with zero balances: n"; 59 break; 60 61 case CREDIT_BALANCE: 62 cout << "n. Accounts with credit balances: n"; 63 break; 64 65 case DEBIT_BALANCE: 66 cout << "n. Accounts with debit balances: n"; 67 break; 68 69 } // end switch 70 fig 14_08. cp p (3 of 6) 19
70 // read account, name and balance from file 71 in. Client. File >> account >> name >> balance; 72 73 // display file contents (until eof) 74 while ( !in. Client. File. eof() ) { 75 76 // display record 77 if ( should. Display( request, balance ) ) 78 output. Line( account, name, balance ); 79 70 // read account, name and balance from file Use clear to reset eof. Use 81 in. Client. File >> account >> name >> balance; seekg to set file position 82 } // end inner while pointer to beginning of file. 83 84 in. Client. File. clear(); // reset eof for next input 85 in. Client. File. seekg( 0 ); // move to beginning of file 86 request = get. Request(); // get additional request from user 87 } // end outer while fig 14_08. cp p (4 of 6) 20
14. 6 Updating Sequential-Access Files n Updating sequential files q q Risk overwriting other data Example: change name "White" to "Worthington" n Old data 300 White 0. 00 400 Jones 32. 87 n Insert new data 300 Worthington 0. 00 300 White 0. 00 400 Jones 32. 87 Data gets overwritten 300 Worthington 0. 00 ones 32. 87 q q Formatted text different from internal representation Problem can be avoided, but awkward 21
14. 7 n Instant access q Want to locate record quickly n q n Random-Access Files Airline reservations, ATMs Sequential files must search through each one Random-access files are solution q q q Instant access Insert record without destroying other data Update/delete items without changing other data 22
14. 7 n Random-Access Files C++ imposes no structure on files q q Programmer must create random-access files Simplest way: fixed-length records n Calculate position in file from record size and key 23
14. 8 Creating a Random-Access File n "1234567" (char *) vs 1234567 (int) q q char * takes 8 bytes (1 for each character + null) int takes fixed number of bytes (perhaps 4) n n 123 same size in bytes as 1234567 << operator and write() q q out. File << number n Outputs number (int) as a char * n Variable number of bytes out. File. write( const char *, size ); n n Outputs raw bytes Takes pointer to memory location, number of bytes to write q q Copies data directly from memory into file Does not convert to char * 24
14. 8 Creating a Random-Access File n Example out. File. write( reinterpret_cast<const char *>(&number), sizeof( number ) ); q &number is an int * n q sizeof(number) n q q Size of number (an int) in bytes read function similar (more later) Must use write/read between compatible machines n q Convert to const char * with reinterpret_cast Only when using raw, unformatted data Use ios: : binary for raw writes/reads 25
14. 8 Creating a Random-Access File n Usually write entire struct or object to file n Problem statement q q q Credit processing program Store at most 100 fixed-length records Record n n n q Account operations n n Account number (key) First and last name Balance Update, create new, delete, list all accounts in a file Next: program to create blank 100 -record file 26
1 // Fig. 14. 10: client. Data. h 2 // Class Client. Data definition used in Fig. 14. 12–Fig. 14. 15. 3 #ifndef CLIENTDATA_H 4 #define CLIENTDATA_H 5 #include <string> 6 #include <iostream> 7 using std: : string; 8 9 class Client. Data { 10 public: 11 // default Client. Data constructor 12 Client. Data( int = 0, string = "", double = 0. 0 ); 13 14 // accessor functions for account. Number 15 void set. Account. Number( int ); 16 int get. Account. Number() const; 17 18 // accessor functions for last. Name 19 void set. Last. Name( string ); 20 string get. Last. Name() const; client. Data. h (1 of 2) 27
21 // accessor functions for first. Name 22 void set. First. Name( string ); 23 string get. First. Name() const; 24 25 // accessor functions for balance 26 void set. Balance( double ); 27 double get. Balance() const; 28 29 private: 30 int account. Number; 31 char last. Name[ 15 ]; 32 char first. Name[ 10 ]; 33 double balance; 34 35 }; // end class Client. Data 36 37 #endif client. Data. h (2 of 2) 28
1 // Fig. 14. 12: fig 14_12. cpp 2 // Creating a randomly accessed file. 3 #include <iostream> 4 using std: : cerr; 5 using std: : endl; 6 using std: : ios; fig 14_12. cpp (1 of 2) 7 8 #include <fstream> 9 using std: : ofstream; 10 11 #include <cstdlib> 12 #include "client. Data. h" // Client. Data class definition 13 14 int main() { 15 ofstream out. Credit( "credit. dat", ios: : binary ); 16 17 // exit program if ofstream could not open file 18 if ( !out. Credit ) { 19 cerr << "File could not be opened. " << endl; 20 exit( 1 ); 21 } // end if 29
22 23 // create Client. Data with no information 24 Client. Data blank. Client; 25 26 // output 100 blank records to file 27 for ( int i = 0; i < 100; i++ ) 28 out. Credit. write( 29 reinterpret_cast< const char * >( &blank. Client ), 30 sizeof( Client. Data ) ); 31 32 return 0; 33 34 } // end main fig 14_12. cp p (2 of 2) 30
14. 9 Writing Data Randomly to a Random-Access File n Use seekp to write to exact location in file q Where does the first record begin? n q The second record? n q Byte 0 + sizeof(object) Any record? n (Recordnum - 1) * sizeof(object) 31
19 int main() { 20 int account. Number; 21 char last. Name[ 15 ]; 22 char first. Name[ 10 ]; 23 double balance; fig 14_13. cp p (2 of 4) 24 25 ofstream out. Credit( "credit. dat", ios: : binary ); 26 27 // exit program if ofstream cannot open file 28 if ( !out. Credit ) { 29 cerr << "File could not be opened. " << endl; 30 exit( 1 ); 31 } // end if 32 33 cout << "Enter account number " 34 << "(1 to 100, 0 to end input)n? "; 35 36 // require user to specify account number 37 Client. Data client; 38 cin >> account. Number; 39 client. set. Account. Number( account. Number ); 32
fig 14_13. cpp (3 of 4) 40 // user enters information, which is copied into file 41 while ( client. get. Account. Number() > 0 && 42 client. get. Account. Number() <= 100 ) { 43 44 // user enters last name, first name and balance 45 cout << "Enter lastname, firstname, balancen? "; 46 cin >> setw( 15 ) >> last. Name; 47 cin >> setw( 10 ) >> first. Name; 48 cin >> balance; 49 50 // set record last. Name, first. Name and balance values 51 client. set. Last. Name( last. Name ); 52 client. set. First. Name( first. Name ); 53 client. set. Balance( balance ); 54 55 // seek position in file of user-specified record 56 out. Credit. seekp( ( client. get. Account. Number() - 1 ) * sizeof( Client. Data ) ); 57 58 // write user-specified information in file 33 59 out. Credit. write(reinterpret_cast< const char * >( &client ), sizeof( Client. Data ) );
60 // enable user to specify another account number 61 cout << "Enter account numbern? "; 62 cin >> account. Number; 63 client. set. Account. Number( account. Number ); 64 65 } // end while 66 67 return 0; 68 69 } // end main fig 14_13. cp p (4 of 4) 34
Enter account number (1 to ? 37 Enter lastname, firstname, ? Barker Doug 0. 00 Enter account number ? 29 Enter lastname, firstname, ? Brown Nancy -24. 54 Enter account number ? 96 Enter lastname, firstname, ? Stone Sam 34. 98 Enter account number ? 88 Enter lastname, firstname, ? Smith Dave 258. 34 Enter account number ? 33 Enter lastname, firstname, ? Dunn Stacey 314. 33 Enter account number ? 0 100, 0 to end input) fig 14_13. cpp output (1 of 1) balance Notice that accounts can be created in any order. balance 35
14. 10 Reading Data Sequentially from a Random-Access File n read - similar to write q q Reads raw bytes from file into memory in. File. read( reinterpret_cast<char *>( &number ), sizeof( int ) ); n n q Do not use in. File >> number with raw bytes n n &number: location to store data sizeof(int): how many bytes to read >> expects char * Upcoming program q q Output data from a random-access file Go through each record sequentially n If no data (account. Number == 0) then skip 36
26 int main() { 27 ifstream in. Credit( "credit. dat", ios: : in ); 28 29 // exit program if ifstream cannot open file 30 if ( !in. Credit ) { 31 cerr << "File could not be opened. " << endl; 32 exit( 1 ); 33 } // end if 34 35 cout << left << setw( 10 ) << "Account" << setw( 16 ) 36 << "Last Name" << setw( 11 ) << "First Name" << left 37 << setw( 10 ) << right << "Balance" << endl; 38 39 Client. Data client; // create record 40 41 // read first record from file 42 in. Credit. read( reinterpret_cast< char * >( &client ), 43 sizeof( Client. Data ) ); 44 fig 14_14. cpp (2 of 3) 37
45 // read all records from file 46 while ( in. Credit && !in. Credit. eof() ) { 47 // display record 48 if ( client. get. Account. Number() != 0 ) 49 output. Line( cout, client ); fig 14_14. cpp (3 of 3) 50 51 // read next from file 52 in. Credit. read( reinterpret_cast< char * >( &client ), 53 sizeof( Client. Data ) ); 54 } // end while 55 56 return 0; 57 } // end main 58 59 // display single record 60 void output. Line( ostream &output, const Client. Data &record ) { 61 output << left << setw( 10 ) << record. get. Account. Number() 62 << setw( 16 ) << record. get. Last. Name(). data() 63 << setw( 11 ) << record. get. First. Name(). data() 64 << setw( 10 ) << setprecision( 2 ) << right << fixed 65 << showpoint << record. get. Balance() << endl; 66 } // end output. Line 38
Account 29 33 37 88 96 Last Name Brown Dunn Barker Smith Stone First Name Nancy Stacey Doug Dave Sam fig 14_14. cpp output (1 of 1) Balance -24. 54 314. 33 0. 00 258. 34 34. 98 39
- Slides: 39