Chapter-4-File Input-Output in CPP

Download as pdf or txt
Download as pdf or txt
You are on page 1of 68

File Input/Output Operations – in C++

Persistent Data storage in Files –File Input output streams

Chapter 4- File Input/Output Operations in C++


Chapter Objectives
 The need for file I/O
 I/O Stream class hierarchy
 Creating file streams, connecting to and closing a file
 Writing and reading a charter to file
 Writing and Reading formatted text(sequential) files
 File Stream pointers and their manipulations
 Writing and reading binary files

Chapter 4- File I/O Operations in C++ 2


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
o 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 ‘W’ ‘h’ ‘y’ ‘’ ‘d’ ‘o’ ….

CHAPTER 4- FILE I/O OPERATIONS IN C++

3
The Data Hierarchy

CHAPTER 4- FILE I/O OPERATIONS IN C++

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)
CHAPTER 4- FILE I/O OPERATIONS IN C++
5
The Interactive I/O Streams and your C++ Program

Program

Output Stream
Input Stream
(istream) (ostream)

I/O Devices

Chapter 4- File I/O Operations in C++ 6


The File I/O Streams and your C++ Program

Program

Output Stream
Input Stream
(ifstream) (ofstream)

File on Disk

Chapter 4- File I/O Operations in C++ 7


Hierarchy of the stream classes

ios

istream ostream

ifstream iostream ofstream

fstream
Chapter 4- File I/O Operations in C++ 8
Headers required for stream processing

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

o <fstream.h>

• class ifstream - input from file

• class ofstream – output to file

• class fstream - either input or output from/to file

CHAPTER 4- FILE I/O OPERATIONS IN C++

9
Creating Streams
 Before we can use an input or output stream in a program, we
must "create" it

//create an input stream


ifstream in_stream;

//create an output stream


ofstream out_stream;
CHAPTER 4- FILE I/O OPERATIONS IN C++

10
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
");
o it also deletes the previous contents of
the file
CHAPTER 4- FILE I/O OPERATIONS IN C++

11
Creating and connecting streams to files in one statement

ifstream in_stream(“file.txt”);

ofstream out_stream(“file.txt”);

CHAPTER 4- FILE I/O OPERATIONS IN C++

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

 out_stream.close();
o 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 connected
to it, we have this situation
CHAPTER 4- FILE I/O OPERATIONS IN C++

13
Checking for Failure with File Commands
void 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);
}
//....
}
CHAPTER 4- FILE I/O OPERATIONS IN C++

14
Character Input
Input using get()
 we can extract or read single characters from the file using the member function
"get(...)“
 in_stream.get(ch); has two effects:
o the variable "ch" is assigned the value "'4'", and
o the ifstream "in_stream" is re- positioned so as to be ready to input the
next character in the file.
o Diagrammatically, the new situation is:

CHAPTER 4- FILE I/O OPERATIONS IN C++

15
Character Output
Output 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:

CHAPTER 4- FILE I/O OPERATIONS IN C++

16
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

CHAPTER 4- FILE I/O OPERATIONS IN C++

17
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”

CHAPTER 4- FILE I/O OPERATIONS IN C++

18
#include <iostream> #include <fstream>
#include <conio> #include <stdlib>
void main()
{
char character;
ifstream in_stream; //create input stream
ofstream 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 stream
in_stream.close(); //disconnect stream
CHAPTER 4- FILE I/O OPERATIONS IN C++
} 19
Input and output using >>(read) and <<(write) a file
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++ << ' ';
CHAPTER 4- FILE I/O OPERATIONS IN C++

20
out_stream.close();
Input and output using >>(read) and <<(write) a file cont’d…
/* 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";
CHAPTER 4- FILE I/O OPERATIONS IN C++

21
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";
}
CHAPTER 4- FILE I/O OPERATIONS IN C++

22
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…
CHAPTER 4- FILE I/O OPERATIONS IN C++

23
Input and output using >> and <<
//…contd from previous slide
int account;
char name[ 30 ];
float balance;
while ( cin >> account >> name >> balance )
{
outClientFile << account << ' ' << name
<< ' ' << balance << '\n';
cout << "? ";
}
getch();
}
CHAPTER 4- FILE I/O OPERATIONS IN C++

24
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 fails
CHAPTER 4- FILE I/O OPERATIONS IN C++

25
File open modes (defaults)
class default open mode parameter
 ofstream ios::out
 ifstream ios::in

CHAPTER 4- FILE I/O OPERATIONS IN C++

26
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 open modes
outClientFile>>account>>name>>balance;
cout<<account<<" "<<name<<" "<<balance;
outClientFile<<“writing something new!";
CHAPTER 4- FILE I/O OPERATIONS IN C++

27
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 );
}
CHAPTER 4- FILE I/O OPERATIONS IN C++

28
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‘;}
CHAPTER 4- FILE I/O OPERATIONS IN C++ 29
Exercise
 Design and implement a program that computes the average of
a sequence of numbers stored in a file

CHAPTER 4- FILE I/O OPERATIONS IN C++

30
Algorithm
0. Prompt for input file name
1. Read name of input file from cin into inFileName
2. Open connection named fin to file named in inFileName
3. Initialize sum, count to zero.
4. Read a value from fin into number
5. 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 message
End if
CHAPTER 4- FILE I/O OPERATIONS IN C++

31
#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
CHAPTER 4- FILE I/O OPERATIONS IN C++
//average 32
fin>>number; //read number
while(!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;
}
CHAPTER 4- FILE I/O OPERATIONS IN C++ 33
Four types functions to manipulate File Pointers

seekg()
seekp()
tellg()
tellp()

Chapter 4- File I/O Operations in C++ 34


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:
o seekg (seek get) for istream class
o seekp (seek put) for ostream class
CHAPTER 4- FILE I/O OPERATIONS IN C++

35
CHAPTER 4- FILE I/O OPERATIONS IN C++
36
Examples of moving a file pointer
 fileObject.seekg( 0 );
o reposition the file-position pointer to the beginning of the file
(location 0) attached to fileObject
 fileObject.seekg(n)
o position to the nth byte of fileObject (assumes ios::beg)
 fileObject.seekg( n,ios::curr );
o position n bytes forward in fileObject
 fileObject.seekg( n, ios::end );
o position n bytes back from end of fileObject
 fileObject.seekg( 0, ios::end );
o position at end of fileObject
The same operations can be performed using ostream
CHAPTER 4- FILE I/O OPERATIONS IN C++

37
member function seekp
Getting Current location of the file pointer
 tellg() tell get and
 tellp() tell put
 Member functions tellg() and tellp() are provided to return
the current locations of the get and put pointers, respectively
 long location = fileObject.tellg();

CHAPTER 4- FILE I/O OPERATIONS IN C++

38
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
o 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)
CHAPTER 4- FILE I/O OPERATIONS IN C++

39
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

CHAPTER 4- FILE I/O OPERATIONS IN C++

40
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
o the file should be opened in the binary mode (ios::binary)
o member functions read() of the ostream class and write() of the
istream class will be used for reading/writing data from/to disk
CHAPTER 4- FILE I/O OPERATIONS IN C++

41
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
CHAPTER 4- FILE I/O OPERATIONS IN C++

42
reinterpret_cast
 Unfortunately, most pointers that we pass to the 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
o You can also use this cast operator to convert
between pointer and integer types, and vice versa
CHAPTER 4- FILE I/O OPERATIONS IN C++

43
reinterpret_cast
 A reinterpret_cast is performed at compile time and does not change
the value of the object to which its operand points
o 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
CHAPTER 4- FILE I/O OPERATIONS IN C++

44
Example of a Program that Creates a Random Access File

//file: clientData.h
struct clientData {
int accountNumber;
string lastName;
string firstName;
float balance;
};
CHAPTER 4- FILE I/O OPERATIONS IN C++

45
// 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,
CHAPTER 4- FILE I/O OPERATIONS INsizeof(
C++ clientData ) );} 46
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 );
}4- FILE I/O OPERATIONS IN C++
CHAPTER

47
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;
}
CHAPTER 4- FILE I/O OPERATIONS IN C++ 48
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 );
}
CHAPTER 4- FILE I/O OPERATIONS IN C++

49
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 ) );
}
CHAPTER 4- FILE I/O OPERATIONS IN C++ 50

}
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';
}

CHAPTER 4- FILE I/O OPERATIONS IN C++ 51


Updating a record using random access
void 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 file
ClientData client;
inFile.read( (char*)&client, sizeof( ClientData ) );

CHAPTER 4- FILE I/O OPERATIONS IN C++

52
// update record
if ( 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
CHAPTER 4- FILE I/O OPERATIONS File.write(
IN C++ (char*) &client, 53

sizeof( ClientData ) ); }// end if


else {
// display error if account does not exist
cerr << "Account #" << accNumber
<< " has no information." << endl;
}

CHAPTER 4- FILE I/O OPERATIONS IN C++ 54


Deleting a record from a random access file
void 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 ) );
CHAPTER 4- FILE I/O OPERATIONS IN C++

55
// delete record, if record exists in file
if ( 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
CHAPTER 4- FILE I/O OPERATIONS IN C++ cerr << "Account #" << accNumber << " is 56

empty.\n"; }
Summary
 The fstream library defines two classes:

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


and
o ofstream, for creating connections between programs and output files.
 Both ifstream and ofstream objects are created in a similar fashion.

CHAPTER 4- FILE I/O OPERATIONS IN C++

57
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 statements
ifstream 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

CHAPTER 4- FILE I/O OPERATIONS IN C++

58
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

CHAPTER 4- FILE I/O OPERATIONS IN C++

59
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”);
CHAPTER 4- FILE I/O OPERATIONS IN C++

60
Summary (contd)
 Once an ifstream (or ofstream) has been opened, it can be read from using the usual
input (or output) operations:
o input: >>, get(), getline(), ...
o output: <<, put(), ...
 In general, anything that can be done to an istream (or ostream) can be done to an
ifstream (or ofstream).

CHAPTER 4- FILE I/O OPERATIONS IN C++

61
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.

CHAPTER 4- FILE I/O OPERATIONS IN C++

62
Summary (contd)
 The eof() member function provides a convenient way
to build input loops that employ no redundant code
fin>> someValue
while(!fin.eof())
{
// ... process someValue
fin >> someValue;
}
CHAPTER 4- FILE I/O OPERATIONS IN C++

63
Summary (contd)
 Once we are done using an ifstream (or ofstream), it can
be closed using the close() function member:
o fin.close();
o 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.
CHAPTER 4- FILE I/O OPERATIONS IN C++

64
Summary (contd)
To manipulate the read-position within an ifstream, the libraries provide these:
o tellg() // returns offset of current
read-position from
beginning of file
o seekg(offset, base) // move read-position
offset bytes from base
(one of ios::beg,
ios::cur, or
ios::end)

CHAPTER 4- FILE I/O OPERATIONS IN C++

65
Summary (contd)
To manipulate the write-position within an ofstream, the libraries provide these:
o tellp() // returns offset of current
write-position from
beginning of file
o seekp(offset, base) // move write-position
offset bytes from base
(one of ios::beg,
ios::cur, or
ios::end)

CHAPTER 4- FILE I/O OPERATIONS IN C++

66
Other Operations
 To look at the next character in an ifstream without advancing the read-position (i.e.,
without reading it), the libraries provide:
o peek() // returns next char in the stream without reading it
 To “unread” the last char that was read, the libraries provide:
o 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:
o ignore(n, stopChar) // skip past n chars,
or until stopChar
is encountered
CHAPTER 4- FILE I/O OPERATIONS IN C++

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

CHAPTER 4- FILE I/O OPERATIONS IN C++

68

You might also like