Chapter-4-File Input-Output in CPP
Chapter-4-File Input-Output in CPP
Chapter-4-File Input-Output in CPP
3
The Data Hierarchy
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)
Program
Output Stream
Input Stream
(istream) (ostream)
I/O Devices
Program
Output Stream
Input Stream
(ifstream) (ofstream)
File on Disk
ios
istream ostream
fstream
Chapter 4- File I/O Operations in C++ 8
Headers required for stream processing
o <fstream.h>
9
Creating Streams
Before we can use an input or output stream in a program, we
must "create" it
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”);
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:
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:
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
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”
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
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
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>
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
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()
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();
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
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 };
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;
}
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';
}
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
55
// delete record, if record exists in file
if ( accNumber != 0 )
{
clientData blankClient = { 0, "noname ", "noname ",
0.0 }; // create blank record
empty.\n"; }
Summary
The fstream library defines two classes:
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
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
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).
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.
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)
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)
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
68