Fundamentals of Programming Session 26 Instructor: Reza - - PowerPoint PPT Presentation

fundamentals of programming
SMART_READER_LITE
LIVE PREVIEW

Fundamentals of Programming Session 26 Instructor: Reza - - PowerPoint PPT Presentation

Fundamentals of Programming Session 26 Instructor: Reza Entezari-Maleki Email: entezari@ce.sharif.edu 1 Fall 2013 These slides have been created using Deitels slides Sharif University of Technology Outlines Reading Data from a


slide-1
SLIDE 1

Fall 2013

Instructor: Reza Entezari-Maleki

Email: entezari@ce.sharif.edu

Sharif University of Technology

1

Fundamentals of Programming

Session 26

These slides have been created using Deitel’s slides

slide-2
SLIDE 2

Outlines

 Reading Data from a Sequential-Access File  Updating Sequential-Access Files  Random-Access Files  Creating a Random-Access File  Writing Data Randomly to a Random-Access File  Reading Data Sequentially from a Random-Access

File

2

slide-3
SLIDE 3

 File position pointers

 Number of next byte to read/write  Functions to reposition pointer

 seekg (seek get for istream class)  seekp (seek put for ostream class)

 seekg and seekp take offset and direction

 Offset: number of bytes relative to direction  Direction (ios::beg default)

 ios::beg - relative to beginning of stream  ios::cur - relative to current position  ios::end - relative to end

3

Reading Data from a Sequential-Access File …

slide-4
SLIDE 4

 Examples

 fileObject.seekg(0)

 Goes to front of file (location 0) because ios::beg is default

 fileObject.seekg(n)

 Goes to nth byte from beginning

 fileObject.seekg(n, ios::cur)

 Goes n bytes forward

 fileObject.seekg(y, ios::end)

 Goes y bytes back from end

 fileObject.seekg(0, ios::cur)

 Goes to last byte

 seekp similar

4

Reading Data from a Sequential-Access File …

slide-5
SLIDE 5

 To find pointer location

 tellg and tellp  location = fileObject.tellg()

 Upcoming example

 Credit manager program  List accounts with zero balance, credit, and debit

5

Reading Data from a Sequential-Access File …

slide-6
SLIDE 6

6

1 #include <iostream> 2 using std::cout; 3 using std::cin; 4 using std::ios; 5 using std::cerr; 6 using std::endl; 7 using std::fixed; 8 using std::showpoint; 9 using std::left; 10 using std::right; 11 #include <fstream> 12 using std::ifstream; 13 #include <iomanip> 14 using std::setw; 15 using std::setprecision; 16 #include <cstdlib>

slide-7
SLIDE 7

7

17 enum RequestType { ZERO_BALANCE = 1, CREDIT_BALANCE, 18 DEBIT_BALANCE, END }; 19 int getRequest(); 20 bool shouldDisplay( int, double ); 21 void outputLine( int, const char * const, double ); 22 int main() 23 { 24 // ifstream constructor opens the file 25 ifstream inClientFile( "clients.dat", ios::in ); 26 // exit program if ifstream could not open file 27 if ( !inClientFile ) { 28 cerr << "File could not be opened" << endl; 29 exit( 1 ); 30 } // end if 31 int request; 32 int account; 33 char name[ 30 ]; 34 double balance; 35 // get user's request (e.g., zero, credit or debit balance) 36 request = getRequest();

slide-8
SLIDE 8

8

37 // process user's request 38 while ( request != END ) { 39 switch ( request ) { 40 case ZERO_BALANCE: 41 cout << "\nAccounts with zero balances:\n"; 42 break; 43 case CREDIT_BALANCE: 44 cout << "\nAccounts with credit balances:\n"; 45 break; 46 case DEBIT_BALANCE: 47 cout << "\nAccounts with debit balances:\n"; 48 break; 49 } // end switch

slide-9
SLIDE 9

9

50 // read account, name and balance from file 51 inClientFile >> account >> name >> balance; 52 // display file contents (until eof) 53 while ( !inClientFile.eof() ) { 54 // display record 55 if ( shouldDisplay( request, balance ) ) 56

  • utputLine( account, name, balance );

55 // read account, name and balance from file 57 inClientFile >> account >> name >> balance; 58 } // end inner while 59 inClientFile.clear(); // reset eof for next input 60 inClientFile.seekg( 0 ); // move to beginning of file 61 request = getRequest(); // get additional request from user 62 } // end outer while 63 cout << "End of run." << endl; 64 return 0; // ifstream destructor closes the file 65 } // end main

slide-10
SLIDE 10

10

66 // obtain request from user 67 int getRequest() 68 { 69 int request; 70 // display request options 71 cout << "\nEnter request" << endl 72 << " 1 - List accounts with zero balances" << endl 73 << " 2 - List accounts with credit balances" << endl 74 << " 3 - List accounts with debit balances" << endl 75 << " 4 - End of run" << fixed << showpoint; 76 // input user request 77 do { 78 cout << "\n? "; 79 cin >> request; 80 } while ( request < ZERO_BALANCE || request > END ); 81 return request; 82 } // end function getRequest

slide-11
SLIDE 11

11

83 // determine whether to display given record 84 bool shouldDisplay( int type, double balance ) 85 { 86 // determine whether to display credit balances 87 if ( type == CREDIT_BALANCE && balance > 0 ) 88 return true; 89 // determine whether to display debit balances 90 if ( type == DEBIT_BALANCE && balance < 0 ) 91 return true; 92 // determine whether to display zero balances 93 if ( type == ZERO_BALANCE && balance == 0 ) 94 return true; 95 return false; 96 } // end function shouldDisplay 97 // display single record from file 98 void outputLine( int account, const char * const name, 99 double balance ) 100 { 101 cout << left << setw( 10 ) << account << setw( 13 ) << name 102 << setw( 7 ) << setprecision( 2 ) << right << balance 103 << endl; 104 } // end function outputLine

slide-12
SLIDE 12

12

Enter request 1 - List accounts with zero balances 2 - List accounts with credit balances 3 - List accounts with debit balances 4 - End of run ? 1 Accounts with zero balances: 300 White 0.00 Enter request 1 - List accounts with zero balances 2 - List accounts with credit balances 3 - List accounts with debit balances 4 - End of run ? 3 Accounts with debit balances: 400 Stone -42.16

slide-13
SLIDE 13

13

Enter request 1 - List accounts with zero balances 2 - List accounts with credit balances 3 - List accounts with debit balances 4 - End of run ? 2 Accounts with credit balances: 100 Jones 24.98 200 Doe 345.67 500 Rich 224.62 Enter request 1 - List accounts with zero balances 2 - List accounts with credit balances 3 - List accounts with debit balances 4 - End of run ? 4 End of run.

slide-14
SLIDE 14

 Updating sequential files

 Risk overwriting other data  Example: change name "White" to "Worthington"

 Old data

300 White 0.00 400 Jones 32.87

 Insert new data

 Formatted text different from internal representation  Problem can be avoided, but awkward

14

Updating Sequential-Access Files

300 White 0.00 400 Jones 32.87 300 Worthington 0.00ones 32.87 300 Worthington 0.00

Data gets overwritten

slide-15
SLIDE 15

 Instant access

 Want to locate record quickly

 Airline reservations, ATMs

 Sequential files must search through each one

 Random-access files are solution

 Instant access  Insert record without destroying other data  Update/delete items without changing other data

15

Random-Access Files

slide-16
SLIDE 16

 C++ imposes no structure on files

 Programmer must create random-access files  Simplest way: fixed-length records

 Calculate position in file from record size and key

16

Random-Access Files …

200 300 400 500

byte offsets

} } } } } } }

100

100

bytes

100

bytes

100

bytes

100

bytes

100

bytes

100

bytes

slide-17
SLIDE 17

 "1234567" (char *) vs 1234567 (int)

 char * takes 8 bytes (1 for each character + null)  int takes fixed number of bytes (perhaps 4)

 123 same size in bytes as 1234567

 << operator and write()

 outFile << number

 Outputs number (int) as a char *  Variable number of bytes

 outFile.write( const char *, size );

 Outputs raw bytes  Takes pointer to memory location, number of bytes to write

 Copies data directly from memory into file

17

Creating a Random-Access File

slide-18
SLIDE 18

 Example

  • utFile.write( reinterpret_cast<const char *>(&number),

sizeof( number ) );

 &number is an int *

 Convert to const char * with reinterpret_cast

 sizeof(number)

 Size of number (an int) in bytes

 read function similar (more later)  Must use write/read between compatible machines

 Only when using raw, unformatted data

 Use ios::binary for raw writes/reads

18

Creating a Random-Access File …

slide-19
SLIDE 19

 Usually write entire struct or object to file  Problem statement

 Credit processing program  Store at most 100 fixed-length records  Record

 Account number (key)  First and last name  Balance

 Account operations

 Update, create new, delete, list all accounts in a file

 Next: program to create blank 100-record file

19

Creating a Random-Access File …

slide-20
SLIDE 20

20

1 #include <iostream> 2 #include <fstream> 3 #include <cstdlib> 4 #include <cstring> 5 using std::cerr; 6 using std::endl; 7 using std::ios; 8 using std::ofstream; 9 using std::string; 10 class ClientData { 11 public: 12 // default ClientData constructor 13 ClientData( int = 0, string = "", string = "", double = 0.0 ); 14 // accessor functions for accountNumber 15 void setAccountNumber( int ); 16 int getAccountNumber(); 17 // accessor functions for lastName 18 void setLastName(char *); 19 char * getLastName();

slide-21
SLIDE 21

21

20 // accessor functions for firstName 21 void setFirstName(char *); 22 char * getFirstName(); 23 // accessor functions for balance 24 void setBalance( double ); 25 double getBalance(); 26 private: 27 int accountNumber; 28 char lastName[ 15 ]; 29 char firstName[ 10 ]; 30 double balance; 31 }; // end class ClientData

slide-22
SLIDE 22

22

32 // default ClientData constructor 33 ClientData::ClientData( int accountNumberValue, 34 char * lastNameValue, char * firstNameValue, 35 double balanceValue ) 36 { 37 setAccountNumber( accountNumberValue ); 38 setLastName( lastNameValue ); 39 setFirstName( firstNameValue ); 40 setBalance( balanceValue ); 41 } // end ClientData constructor 42 // get account-number value 43 int ClientData::getAccountNumber() 44 { 45 return accountNumber; 46 } // end function getAccountNumber

slide-23
SLIDE 23

23

47 // set account-number value 48 void ClientData::setAccountNumber( int accountNumberValue ) 49 { 50 accountNumber = accountNumberValue; 51 } // end function setAccountNumber 52 // get last-name value 53 char * ClientData::getLastName() 54 { 55 return lastName; 56 } // end function getLastName 57 // set last-name value 58 59 void ClientData::setLastName(char * lastNameValue) 60 { 61 // copy at most 15 characters from string to lastName 62 int length = strlen( lastNameValue ); 63 length = ( length < 15 ? length : 14 ); 64 strncpy( lastName, lastNameValue, length ); 65 // append null character to lastName 66 lastName[ length ] = '\0';

slide-24
SLIDE 24

24

67 } // end function setLastName 68 // get first-name value 69 char * ClientData::getFirstName() 70 { 71 return firstName; 72 } // end function getFirstName 73 // set first-name value 74 75 void ClientData::setFirstName(char * firstNameValue) 76 { 77 // copy at most 10 characters from string to firstName 78 int length = strlen( firstNameValue ); 79 length = ( length < 10 ? length : 9 ); 80 strncpy( firstName, firstNameValue, length ); 81 // append new-line character to firstName 82 firstName[ length ] = '\0'; 83 } // end function setFirstName

slide-25
SLIDE 25

25

84 // get balance value 85 double ClientData::getBalance() 86 { 87 return balance; 88 89 } // end function getBalance 90 91 // set balance value 92 void ClientData::setBalance( double balanceValue ) 93 { 94 balance = balanceValue; 95 96 } // end function setBalance

slide-26
SLIDE 26

26

97 int main() 98 { 99 ofstream outCredit( "credit.dat", ios::binary ); 100 // exit program if ofstream could not open file 101 if ( !outCredit ) { 102 cerr << "File could not be opened." << endl; 103 exit( 1 ); 104 } // end if 105 // create ClientData with no information 106 ClientData blankClient; 107 108 // output 100 blank records to file 109 for ( int i = 0; i < 100; i++ ) 110

  • utCredit.write(

111 reinterpret_cast< const char * >( &blankClient ), 112 sizeof( ClientData ) ); 113 114 return 0; 115 116 } // end main

slide-27
SLIDE 27

 Use seekp to write to exact location in file

 Where does the first record begin?

 Byte 0

 The second record?

 Byte 0 + sizeof(object)

 Any record?

 (Recordnum - 1) * sizeof(object)

27

Writing Data Randomly to a Random-Access File

slide-28
SLIDE 28

28

1 #include <iostream> 2 using std::cerr; 3 using std::endl; 4 using std::cout; 5 using std::cin; 6 using std::ios; 7 #include <iomanip> 8 using std::setw; 9 #include <fstream> 10 using std::ofstream; 11 #include <cstdlib> 12 #include "clientData.h" // ClientData class definition

slide-29
SLIDE 29

29

13 int main() 14 { 15 int accountNumber; 16 char lastName[ 15 ]; 17 char firstName[ 10 ]; 18 double balance; 19 ofstream outCredit( "credit.dat", ios::binary ); 20 // exit program if ofstream cannot open file 21 if ( !outCredit ) { 22 cerr << "File could not be opened." << endl; 23 exit( 1 ); 24 } // end if 25 cout << "Enter account number " 26 << "(1 to 100, 0 to end input)\n? "; 27 // require user to specify account number 28 cin >> accountNumber; 29 ClientData client; 30 client.setAccountNumber( accountNumber );

slide-30
SLIDE 30

30

31 // user enters information, which is copied into file 32 while ( client.getAccountNumber() > 0 && 33 client.getAccountNumber() <= 100 ) { 34 // user enters last name, first name and balance 35 cout << "Enter lastname, firstname, balance\n? "; 36 cin >> setw( 15 ) >> lastName; 37 cin >> setw( 10 ) >> firstName; 38 cin >> balance; 39 // set record lastName, firstName and balance values 40 client.setLastName( lastName ); 41 client.setFirstName( firstName ); 42 client.setBalance( balance ); 43 // seek position in file of user-specified record 44

  • utCredit.seekp( ( client.getAccountNumber() - 1 ) *

45 sizeof( ClientData ) ); 46 // write user-specified information in file 47

  • utCredit.write(

48 reinterpret_cast< const char * >( &client ), 49 sizeof( ClientData ) );

slide-31
SLIDE 31

31

50 // enable user to specify another account number 51 cout << "Enter account number\n? "; 52 cin >> accountNumber; 53 client.setAccountNumber( accountNumber ); 54 55 } // end while 56 57 return 0; 58 59 } // end main

slide-32
SLIDE 32

32

Enter account number (1 to 100, 0 to end input) ? 37 Enter lastname, firstname, balance ? Barker Doug 0.00 Enter account number ? 29 Enter lastname, firstname, balance ? Brown Nancy -24.54 Enter account number ? 96 Enter lastname, firstname, balance ? Stone Sam 34.98 Enter account number ? 88 Enter lastname, firstname, balance ? Smith Dave 258.34 Enter account number ? 33 Enter lastname, firstname, balance ? Dunn Stacey 314.33 Enter account number ? 0

slide-33
SLIDE 33

 read - similar to write

 Reads raw bytes from file into memory

 inFile.read( reinterpret_cast<char *>( &number ),

sizeof( int ) );

 &number: location to store data  sizeof(int): how many bytes to read

 Do not use inFile >> number with raw bytes

 >> expects char *

 Upcoming program

 Output data from a random-access file  Go through each record sequentially

 If no data (accountNumber == 0) then skip

33

Reading Data Sequentially from a Random-Access File

slide-34
SLIDE 34

34

1 #include <iostream> 2 using std::cout; 3 using std::endl; 4 using std::ios; 5 using std::cerr; 6 using std::left; 7 using std::right; 8 using std::fixed; 9 using std::showpoint; 10 #include <iomanip> 11 using std::setprecision; 12 using std::setw; 13 #include <fstream> 14 using std::ifstream; 15 using std::ostream; 16 #include <cstdlib> // exit protoyype 17 #include "clientData.h" // ClientData class definition

slide-35
SLIDE 35

35

18 void outputLine( ostream&, const ClientData & ); 19 int main() 20 { 21 ifstream inCredit( "credit.dat", ios::in ); 22 // exit program if ifstream cannot open file 23 if ( !inCredit ) { 24 cerr << "File could not be opened." << endl; 25 exit( 1 ); 26 } // end if 27 28 cout << left << setw( 10 ) << "Account" << setw( 16 ) 29 << "Last Name" << setw( 11 ) << "First Name" << left 30 << setw( 10 ) << right << "Balance" << endl; 31 ClientData client; // create record 32 // read first record from file 33 inCredit.read( reinterpret_cast< char * >( &client ), 34 sizeof( ClientData ) );

slide-36
SLIDE 36

36

35 // read all records from file 36 while ( inCredit && !inCredit.eof() ) { 37 // display record 37 if ( client.getAccountNumber() != 0 ) 38

  • utputLine( cout, client );

39 // read next from file 40 inCredit.read( reinterpret_cast< char * >( &client ), 41 sizeof( ClientData ) ); 42 } // end while 43 return 0; 44 } // end main 45 46 // display single record 47 void outputLine( ostream &output, const ClientData &record ) 48 { 49 output << left << setw( 10 ) << record.getAccountNumber() 50 << setw( 16 ) << record.getLastName().data() 51 << setw( 11 ) << record.getFirstName().data() 52 << setw( 10 ) << setprecision( 2 ) << right << fixed 53 << showpoint << record.getBalance() << endl; 54 } // end outputLine

slide-37
SLIDE 37

37

Account Last Name First Name Balance 29 Brown Nancy -24.54 33 Dunn Stacey 314.33 37 Barker Doug 0.00 88 Smith Dave 258.34 96 Stone Sam 34.98

slide-38
SLIDE 38

Thank you