File Handling in C++
-
Upload
bertille-marley -
Category
Documents
-
view
25 -
download
4
description
Transcript of 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
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
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