Classes and Data Abstraction and File Processing 1
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> Notice the header files 11 using std: : ofstream; required for file I/O. 12 13 #include <cstdlib> // exit prototype ofstream object created 14 and used to open file 15 int main() { "clients. dat". If the file does not exist, it is created. 16 // ofstream constructor opens file 17 ofstream out. Client. File( "clients. dat", ios: : out ); 18 fig 14_04. cp p (1 of 2) 12
! operator used to test if the file opened properly. 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 cin is implicitly converted to 28 int account; a pointer. When EOF is encountered, it returns 0 and 29 char name[ 30 ]; the loop stops. 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 << "? "; Write data to file like a File closed when destructor 36 } // end while regular stream. called for object. Can be explicitly closed with 37 return 0; // ofstream destructor closes file close(). 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
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) 19
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 20
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 21
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 22
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 * 23
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 24
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 25
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 6 #include <iostream> Class Client. Data stores 7 using std: : string; the information for each 8 person. 100 blank Client. Data objects will be 9 class Client. Data { written to a file. 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) 26
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) Put limits on the size of the first and last name. account. Number (an int) and balance (double) are already of a fixed size. 27
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 Open a file for raw writing 13 14 int main() { 15 ofstream out. Credit( "credit. dat", ios: : binary ); using an ofstream object and 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 28
22 23 // create Client. Data with no information Create a blank object. Use 24 Client. Data blank. Client; write to output the raw data 25 to a file (passing a pointer to the object and its size). 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) 29
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) 30
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(binary) of 4) Open file for raw writing. 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 Get account number, put into 36 // require user to specify account number object. It has not yet been 37 Client. Data client; written to file. 38 cin >> account. Number; 39 client. set. Account. Number( account. Number ); 31
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 ); Position out. Credit to the proper location in the file 53 client. set. Balance( balance ); (based on the account 54 number). 55 // seek position in file of user-specified record 56 out. Credit. seekp( ( client. get. Account. Number() - 1 ) * sizeof( Client. Data ) ); Write Client. Data object to 57 file at specified position. 58 // write user-specified information in file 32 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) 33
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 34
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 35
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; Read sizeof(Client. Data) bytes and put into object client. This may be an empty 38 record. 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) 36
45 // read all records from file 46 while ( in. Credit && !in. Credit. eof() ) { 47 // display record Loop exits if there is an error 48 if ( client. get. Account. Number() != 0 ) reading (in. Credit == 0) or EOF is found 49 output. Line( cout, client ); fig 14_14. cpp (3 of 3) 50 (in. Credit. eof() == 1) 51 // read next from file 52 in. Credit. read( reinterpret_cast< char * >( &client ), 53 sizeof( Client. Data ) ); Output non-empty accounts. Note that output. Line takes 54 } // end while 55 56 return 0; 57 } // end main 58 an ostream argument. We could easily output to another file (opened with an ofstream object, which derives from ostream). 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 37
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 38
- Slides: 38