File Handling in C++

67
Computer Science Department File Handling in C++

description

File Handling in C++. Why do we need Files?. All the programs we have looked at so far use input only from the keyboard, and output only to the screen Data that is held in variables is temporary and is lost when the program execution is finished - PowerPoint PPT Presentation

Transcript of File Handling in C++

Computer Science Department

File Handling in C++

Computer Science Department

Why do we need Files?

• All the programs we have looked at so far use input only from the keyboard, and output only to the screen– Data that is held in variables is temporary and

is lost when the program execution is finished• In order to store data permanently, we need to

store it in files on the hard disk• The easiest way to think about a file is as a linear

sequence of characters

CPS235: FilesAndStreams 2

‘W’ ‘h’ ‘y’ ‘ ’ ‘d’ ‘o’ ….

Computer Science Department

The Data Hierarchy

CPS235: FilesAndStreams 3

Computer Science Department

CPS235: FilesAndStreams 4

C++ Streams

• Stream– A transfer of information in the form of a

sequence of bytes

• I/O Operations– Input stream: A stream that flows from an input

device to the main memory ( from: keyboard, disk drive, scanner or network connection)

– Output stream: A stream that flows from the main memory to an output device ( to: screen, printer, disk drive or network connection)

Computer Science Department

CPS235: FilesAndStreams 5

Program

I/O Devices

Input Stream (istream)

Output Stream

(ostream)

Computer Science Department

CPS235: FilesAndStreams 6

Program

File on Disk

Input Stream (ifstream)

Output Stream

(ofstream)

Computer Science Department

Headers required for stream processing

– <iostream.h> (cout, cin, cerr, clog)

– <fstream.h>

•class ifstream - input from file

•class ofstream – output to file

•class fstream - either input or output

from/to file

CPS235: FilesAndStreams 7

Computer Science Department

Creating Streams• Before we can use an input or output

stream in a program, we must "create" it

//create an input streamifstream in_stream;

//create an output streamofstream out_stream;

CPS235: FilesAndStreams 8

Computer Science Department

Connecting Streams to Files• Having created a stream, we can connect it to a file using the member

function "open(...)”• in_stream.open(“file.txt");

• out_stream.open(“file.txt");– it also deletes the previous contents of the file

CPS235: FilesAndStreams 9

Computer Science Department

Creating and connecting streams to files in one statement

ifstream in_stream(“file.txt”);

ofstream out_stream(“file.txt”);

CPS235: FilesAndStreams 10

Computer Science Department

Disconnecting Streams from Files• To disconnect a stream from a file, we can use the member function “close(...)”• in_stream.close();

• out_stream.close();– Adds an "end-of-file" marker at the end of the file, so if no data has been output to “file.txt” since "out_stream" was connectedto it, we have this situation

CPS235: FilesAndStreams 11

Computer Science Department

Checking for Failure with File Commandsvoid main()

{

ifstream in_stream;

in_stream.open("Lecture.txt");

if (in_stream.fail()) // or if(!in_stream)

{

cout << "Sorry, the file couldn't be opened!\n";

exit(1);

}

//....

}CPS235: FilesAndStreams 12

Computer Science Department

Character InputInput using get()• we can extract or read single characters from the

file using the member function "get(...)“• in_stream.get(ch); has two effects:

– the variable "ch" is assigned the value "'4'", and – the ifstream "in_stream" is re- positioned so as to

be ready to input the next character in the file. – Diagramatically, the new situation is:

CPS235: FilesAndStreams 13

Computer Science Department

Character OutputOutput using put()• We can write single characters to a file opened

via an ofstream using the member function "put(...)“

• out_stream.put('4'); changes the state to:

CPS235: FilesAndStreams 14

Computer Science Department

Checking for the end of an input file• The eof() function returns true if the end-of-file

is reached• This function can be used in a loop to determine

how many times the get() function should be called to read the complete input file

CPS235: FilesAndStreams 15

Computer Science Department

Example• Write code to copy the contents (character

by character) of a file “old.txt” simultaneously to the screen and to another file “new.txt”

CPS235: FilesAndStreams 16

Computer Science Department

#include <iostream> #include <fstream> #include <conio> #include <stdlib> void main()

{char character;ifstream in_stream; //create input streamofstream out_stream; //create output stream

in_stream.open("old.txt"); //connect to file if(!in_stream)//if file opening fails { cerr<<"file could not be opened"; exit(1); }

out_stream.open("new.txt"); //connect to file

in_stream.get(character); //read 1 char from file

while (!in_stream.eof()) //loop till eof{ cout << character; //display to screen out_stream.put(character); //write to file in_stream.get(character); //read next char}out_stream.close(); //disconnect streamin_stream.close(); //disconnect stream

} CPS235: FilesAndStreams 17

Computer Science Department

Input and output using >> and <<void main()

{

char character;

int number = 51;

int count = 0;

ofstream out_stream;

ifstream in_stream1;

ifstream in_stream2;

/* Create the file */

out_stream.open("Integers.txt");

for (count = 1 ; count <= 5 ; count++)

out_stream << number++ << ' ';

out_stream.close();

CPS235: FilesAndStreams 18

Computer Science Department

Input and output using >> and <</* Count the integers in the file */

in_stream1.open("Integers.txt");

count = 0;

in_stream1 >> number;

while (!in_stream1.eof())

{

count++;

in_stream1 >> number;

}

in_stream1.close();

cout << "There are " << count << " integers in the file,\n";

CPS235: FilesAndStreams 19

Computer Science Department

Input and output using >> and <</* Count the non-blank characters */

in_stream2.open("Integers.txt");

count = 0;

in_stream2 >> character;

while (!in_stream2.eof())

{

count++;

in_stream2 >> character;

}

in_stream2.close();

cout << "represented using " << count << " characters.\n";

}CPS235: FilesAndStreams 20

Computer Science Department

Input and output using >> and <<Another Example

void main(){ ofstream outClientFile( "clients.dat",

ios::out ); if ( !outClientFile ) { cerr << "File could not be opened”; exit(1);

}cout << "Enter the account, name, and balance.\n” << "Enter end-of-file to end input.\n? ";

//contd on next slide…

CPS235: FilesAndStreams 21

Computer Science Department

Input and output using >> and <<//…contd from previous slideint account;char name[ 30 ];float balance;while ( cin >> account >> name >> balance ){ outClientFile << account << ' ' << name << ' ' << balance << '\n'; cout << "? ";}getch();}

CPS235: FilesAndStreams 22

Computer Science Department

File open modes• ios:: app - (append) write all output to the end

of file• ios:: ate - data can be written anywhere in the

file• ios:: binary - read/write data in binary format• ios:: in - (input) open a file for input• ios::out - (output) open a file for output• ios:: trunc -(truncate) discard the files’

contents if it exists• ios::nocreate - if the file does NOT exist, the

open operation fails• ios::noreplace - if the file exists, the open

operation failsCPS235: FilesAndStreams 23

Computer Science Department

File open modes (defaults)• class default mode

parameter • ofstream ios::out • ifstream ios::in

CPS235: FilesAndStreams 24

Computer Science Department

fstream class• An object of fstream opens a file for reading and

writing simultaneously, so we can write something like

fstream outClientFile;

int account; char name[20]; float balance;

outClientFile.open( "clients.dat",ios::out | ios::in ); //specifying multiple modes

outClientFile>>account>>name>>balance;

cout<<account<<" "<<name<<" "<<balance;

outClientFile<<“writing something new!";

CPS235: FilesAndStreams 25

Computer Science Department

Reading and printing a sequential file#include <iostream.h>#include <fstream.h>#include <iomanip.h>#include <stdlib.h>

void outputLine( int, const char *, double );int main(){ // ifstream constructor opens the file ifstream inClientFile

(“Z:\\MyFolder\\clients.dat", ios::in );

if ( !inClientFile ) { cerr << "File could not be opened\n"; exit( 1 ); }

CPS235: FilesAndStreams 26

Computer Science Department

int account; char name[ 30 ]; double balance; cout << setiosflags( ios::left ) << setw(10)

<< "Account“ << setw( 13 ) << "Name" << "Balance\n"; while ( inClientFile >> account >> name >>

balance ) outputLine( account, name, balance ); return 0; // ifstream destructor closes the

file}void outputLine( int acct, const char *name,

double bal ){ cout << setiosflags( ios::left )<< setw(10)

<< acct << setw( 13 ) << name << setw( 7 ) << setprecision( 2 ) << resetiosflags( ios::left )<< setiosflags( ios::fixed | ios::showpoint )<< bal << '\n‘;}

CPS235: FilesAndStreams 27

Computer Science Department

Exercise• Design and implement a program that

computes the average of a sequence of numbers stored in a file

CPS235: FilesAndStreams 28

Computer Science Department

Algorithm0. Prompt for input file name1. Read name of input file from cin into inFileName2. Open connection named fin to file named in

inFileName3. Initialize sum, count to zero.4. Read a value from fin into number5. Loop:

b. If no values left, terminate repetition.c. Add number to sum.d. Increment count.

End loop.6. Close fin.7. If count > 0: display sum / count.

Else display error messageEnd if

CPS235: FilesAndStreams 29

Computer Science Department

#include <iostream> // cin, cout, ...#include <fstream> // ifstream, ofstream, ...#include <string> int main(){ cout << “\nTo average the numbers in an input

file,enter the name of the file: “; string inFileName; cin >> inFileName; ifstream fin(inFileName.data()); // open the

//connection if(!fin)

{cerr<<“File could not be opened”;exit(1);

} double number, sum = 0.0; // variables for int count = 0; // computing

//averageCPS235: FilesAndStreams 30

Computer Science Department

fin>>number; //read numberwhile(!fin.eof())

{ sum += number; // add it to sum

count++; fin >> number; // read next number}

fin.close(); // close fstream

if (count > 0) cout << “\nThe average of the values in “ << inFileName << “ is “ << sum/count <<

endl; else cout << “\n*** No values found in file “ << inFileName << endl;}

CPS235: FilesAndStreams 31

Computer Science Department

Repositioning the file-position pointer• <istream> and <ostream> classes provide

member functions for repositioning the file pointer (the byte number of the next byte in the file to be read or to be written.)

• These member functions are:

– seekg (seek get) for istream class

– seekp (seek put) for ostream class

CPS235: FilesAndStreams 32

Computer Science Department

CPS235: FilesAndStreams 33

Computer Science Department

Examples of moving a file pointer• fileObject.seekg( 0 );

– reposition the file-position pointer to the beginning of the file (location 0) attached to fileObject

• fileObject.seekg(n)– position to the nth byte of fileObject (assumes

ios::beg) • fileObject.seekg( n,ios::curr );

– position n bytes forward in fileObject • fileObject.seekg( n, ios::end );

– position n bytes back from end of fileObject • fileObject.seekg( 0, ios::end );

– position at end of fileObjectThe same operations can be performed using

ostream member function seekpCPS235: FilesAndStreams 34

Computer Science Department

tellg() and tellp()• Member functions tellg() and tellp() are

provided to return the current locations of the get and put pointers, respectively

• long location = fileObject.tellg();

CPS235: FilesAndStreams 35

Computer Science Department

Problems with Sequential Files• Data that is formatted and written to a sequential

file cannot be modified easily without the risk of destroying other data in the file– If we want to modify a record of data, the new

data may be longer than the old one and it could overwrite parts of the record following it

• Sequential files are inappropriate for so-called “instant access” applications in which a particular record of information must be located immediately.

• These applications include banking systems, point-of-sale systems, airline reservation systems, (or any data-base system)

CPS235: FilesAndStreams 36

Computer Science Department

Random Access Files• Instant access is possible with random access

files

• Individual records of a random access file can be accessed directly (and quickly) without searching many other records

CPS235: FilesAndStreams 37

Computer Science Department

Binary I/O• We have seen examples of formatted I/O where

each number is stored as a sequence of characters but it is not always efficient

• It is more efficient to use binary I/O in which numbers are stored in the form of bytes

• So, in binary I/O, an int is always stored in 4 bytes whereas its text version might be 12345 which requires 5 bytes

• For binary I/O– the file should be opened in the binary mode

(ios::binary)– member functions read() of the ostream class and write() of the istream class will be used for reading/writing data from/to disk

CPS235: FilesAndStreams 38

Computer Science Department

Writing Bytes with ostream Member Function write()• To write an int variable num to the file, use:outFile.write( reinterpret_cast< const char *

>(&num ), sizeof( num) );

OR• outFile.write((char *)&num , sizeof( num) ); • This writes the binary version of the number’s 4 bytes• Function write treats its first argument as a group of

bytes by viewing the object in memory as a const char*, which is a pointer to a byte (remember that a char is one byte)

• Starting from that location, function write outputs the number of bytes specified by its second argument, an integer of type size_t

CPS235: FilesAndStreams 39

Computer Science Department

reinterpret_cast• Unfortunately, most pointers that we pass to

function write as the first argument are not of type const char *

• To output objects of other types, we must convert the pointers to those objects to type const char *

• C++ provides the reinterpret_cast operator for cases like this in which a pointer of one type must be cast to an unrelated pointer type

– You can also use this cast operator to convert between pointer and integer types, and vice versa

CPS235: FilesAndStreams 40

Computer Science Department

reinterpret_cast• A reinterpret_cast is performed at compile time

and does not change the value of the object to which its operand points

– Instead, it requests that the compiler reinterpret the operand as the target type (specified in the angle brackets following the keyword reinterpret_cast).

• Here we are using a reinterpret case to convert an int* (the type of the expression &num) to a const char*

• The same conversion would have to be done in case of the read() function of the istream class

CPS235: FilesAndStreams 41

Computer Science Department

Example of a Program that Creates a Random Access File

//file: clientData.h

struct clientData {

int accountNumber;

char lastName[ 15 ];

char firstName[ 10 ];

float balance;

};

CPS235: FilesAndStreams 42

Computer Science Department

// Creating a random access file#include <iostream.h>#include <fstream.h>#include <stdlib.h>#include “clientData.h"void main(){

ofstream outCredit ("credit.dat” , ios::binary);if ( !outCredit ) {

cerr << "File could not be opened." exit( 1 ); } clientData blankClient = { 0, "", "", 0.0 };

for ( int i = 0; i < 100; i++ )outCredit.write((const char*) &blankClient, sizeof( clientData ) );}

CPS235: FilesAndStreams 43

Computer Science Department

Writing data randomly to a random file#include <iostream.h>#include <fstream.h>#include <stdlib.h>#include "clientData.h"void main(){ ofstream outCredit( "credit.dat",ios::ate|

ios::binary );

if ( !outCredit ) { cerr << "File could not be opened." <<

endl; exit( 1 ); }

• CPS235: FilesAndStreams 44

Computer Science Department

cout << "Enter account number”(1 to 100, 0 to end input)\n? ";

clientData client;

cin >> client.accountNumber;

while ( client.accountNumber > 0 && client.accountNumber <= 100 ) {cout << "Enter lastname, firstname, balance\n? ";cin >> client.lastName >> client.firstName >> client.balance;outCredit.seekp( ( client.accountNumber - 1 ) *sizeof( clientData ) );outCredit.write((const char*) &client , sizeof( clientData ) );cout << "Enter account number\n? ";cin >> client.accountNumber;

}

CPS235: FilesAndStreams 45

Computer Science Department

Reading data from a random file sequentially#include <iostream.h>#include <iomanip.h>#include <fstream.h>#include <stdlib.h>#include “clientData.h"void outputLine( ostream&, const clientData & );void main(){ ifstream inCredit( "credit.dat", ios::in ); if ( !inCredit ) { cerr << "File could not be opened." <<

endl; exit( 1 ); }

CPS235: FilesAndStreams 46

Computer Science Department

cout << setiosflags( ios::left ) << setw( 10 ) << "Account” << setw( 16 ) << "Last Name"

<< setw( 11 )<< "First Name" << resetiosflags( ios::left ) << setw( 10 )

<< "Balance" << endl;

clientData client;

inCredit.read( (char*) &client, sizeof( clientData ) ); while ( inCredit && !inCredit.eof() ) { if ( client.accountNumber != 0 ) outputLine( cout, client ); inCredit.read( (char*) &client,

sizeof( clientData ) ); }

}

CPS235: FilesAndStreams 47

Computer Science Department

void outputLine( ostream &output, const clientData &c ){ output << setiosflags( ios::left ) <<

setw( 10 ) << c.accountNumber << setw( 16 ) << c.lastName << setw( 11 ) << c.firstName << setw( 10 ) << setprecision( 2 ) <<

resetiosflags( ios::left )<< setiosflags( ios::fixed |

ios::showpoint ) << c.balance << '\n';}

CPS235: FilesAndStreams 48

Computer Science Department

Updating a record using random accessvoid main() {

fstream File ("credit.dat", ios::binary|ios::out|ios::in);

int accNumber; cout<<"Enter the number of the account you wish to

modify"; cin>>accNumber; // move file-position pointer to correct record

in file inFile.seekg( ( accNumber - 1 ) *

sizeof( ClientData ) );// read the required record from fileClientData client;inFile.read( (char*)&client, sizeof( ClientData ) );

CPS235: FilesAndStreams 49

Computer Science Department

// update recordif ( client.accountNumber != 0 )

{ outputLine( cout, client ); // display the

record // request user to specify transaction cout << "\nEnter charge(+)or payment(-):"; double transaction; // charge or payment cin >> transaction; client.balance += transaction; outputLine( cout, client ); // display the

modified record // move file-position pointer to correct

record in file File.seekp( ( accNumber - 1 ) *

sizeof( ClientData ) );// write updated record over old record in file File.write( (char*) &client,

sizeof( ClientData ) ); }// end if

CPS235: FilesAndStreams 50

Computer Science Department

else {// display error if account does not exist

cerr << "Account #" << accNumber << " has no information." << endl;}

CPS235: FilesAndStreams 51

Computer Science Department

Deleting a record from a random access filevoid main() {

fstream deleteFromFile ("credit.dat", ios::binary|ios::out|ios::in,ios::ate);

cout<<"Enter account number which is to be deleted";

int accNumber; cin>>accNumber; // move file-position pointer to correct record

in file deleteFromFile.seekg( ( accNumber - 1 ) *

sizeof(ClientData ) ); // read record from file clientData client; deleteFromFile.read( (char*)

&client,sizeof( clientData ) );

CPS235: FilesAndStreams 52

Computer Science Department

// delete record, if record exists in fileif ( accNumber != 0 ){

clientData blankClient = { 0, "noname ", "noname ", 0.0 }; // create blank record

// move file-position pointer to correct record

in file deleteFromFile.seekp( ( accNumber - 1 ) *

sizeof( ClientData ) ); // replace existing record with blank record deleteFromFile.write((char*) &blankClient,

sizeof( ClientData ) ); cout << "Account #" << accNumber << "

deleted.\n"; } else // display error if record does not exist cerr << "Account #" << accNumber << " is

empty.\n"; }CPS235: FilesAndStreams 53

Computer Science Department

Summary• The fstream library defines two classes:

– ifstream, for creating connections between programs and input files; and

– ofstream, for creating connections between programs and output files.

• Both ifstream and ofstream objects are created in a similar fashion.

CPS235: FilesAndStreams 54

Computer Science Department

Summary (contd)• If a string inFileName contains the name of an

input file, and string outFileName contains the name of an output file, then the statementsifstream fin(inFileName.data());

ofstream fout(outFileName.data());

define fin and fout as connections to them.• Note that the string member function data() (or c_str()) must be used to retrieve the actual characters of the file’s name

CPS235: FilesAndStreams 55

Computer Science Department

Summary (contd)• If a program tries to open an ifstream to a file

that doesn’t exist, the open is said to fail. • If a program tries to open an ofstream to a file

that doesn’t exist, the open operation creates a new, empty file for output

• If a program tries to open an ofstream to a file that does exist, the open operation (by default) empties that file of its contents, creating a clean file for output

CPS235: FilesAndStreams 56

Computer Science Department

Summary (contd)• To open an existing file without emptying it, the

value ios_base::app can be given as a second argument:ofstream fout(outFileName.data(),ios::app);

• Character string literals can also be used to create ifstream and ofstream objects:

ofstream ferr(“error.log”);

CPS235: FilesAndStreams 57

Computer Science Department

Summary (contd)• Once an ifstream (or ofstream) has been opened,

it can be read from using the usual input (or output) operations:– input: >>, get(), getline(), ...– output: <<, put(), ...

• In general, anything that can be done to an istream (or ostream) can be done to an ifstream (or ofstream).

CPS235: FilesAndStreams 58

Computer Science Department

Summary (contd)• When the most recent input operation found no

data remaining in the file, the input operation is said to fail.

• This can be detected using the ifstream function member eof() (or fail()), which returns true if the last input operation encountered the end of the file, and returns false otherwise.

CPS235: FilesAndStreams 59

Computer Science Department

Summary (contd)• The eof() member function provides a

convenient way to build input loops that employ no redundant codefin>> someValuewhile(!fin.eof()){// ... process someValue

fin >> someValue;}

CPS235: FilesAndStreams 60

Computer Science Department

Summary (contd)• Once we are done using an ifstream (or

ofstream), it can be closed using the close() function member:– fin.close();– fout.close();

• Most systems limit the number of files a program can have open simultaneously, so it is a good practice to close a stream when you are finished using it.

CPS235: FilesAndStreams 61

Computer Science Department

Summary (contd)To manipulate the read-position within an ifstream,

the libraries provide these:– tellg() // returns offset of current

read-position from

beginning of file

– seekg(offset, base) // move read-position offset bytes from

base (one of ios::beg,ios::cur, orios::end)

CPS235: FilesAndStreams 62

Computer Science Department

Summary (contd)To manipulate the write-position within an ofstream,

the libraries provide these:– tellp() // returns offset of current

write-position from

beginning of file

– seekp(offset, base) // move write-position offset bytes from

base (one of ios::beg,ios::cur, orios::end)

CPS235: FilesAndStreams 63

Computer Science Department

Other Operations• To look at the next character in an ifstream without

advancing the read-position (i.e., without reading it), the libraries provide:– peek() // returns next char in the stream without

reading it• To “unread” the last char that was read, the libraries

provide:– unget() // unread char most recently read

• To skip a given number of chars in the stream (or until a particular char is encountered), the libraries provide:– ignore(n, stopChar) // skip past n chars,

or until stopChar is encountered

CPS235: FilesAndStreams 64

Computer Science Department

Status Operations

To determine the status of a stream, the libraries provide these function members:– good() // returns true iff stream is ok– bad() // returns true iff stream is not ok– fail() // returns true iff last operation failed– eof() // returns true iff last file-read failed

CPS235: FilesAndStreams 65

Computer Science Department

Change-State Operations

To change the state of a stream, the libraries provide these function members:– clear() // reset status to good– setstate(b) // set state bit b (one of

ios::goodbit,ios::badbit,ios::failbit, orios::eofbit).

CPS235: FilesAndStreams 66

Computer Science Department

Acknowledgements/Recommended Reading• http://www.doc.ic.ac.uk/~wjk/C++Intro/RobMillerL4.ht

ml• Deitel and Deitel Ch:17

CPS235: FilesAndStreams 67