C++ File I/O - Utah Valley University

Download Report

Transcript C++ File I/O - Utah Valley University

File I/O
Stream Objects
You have been introduced to these stream objects …


cin – the standard input stream - an object of the
istream class,
cout – the standard output stream – an object of the
ostream class
These streams are automatically created for you when
your program executes. To use them you only need to
#include <iostream> and the appropriate using directives.
To do file I/O, we will use a new
set of stream classes
ifstream – objects of this class represent file input
ofstream – objects of this class represent file output
File I/O
When a program takes input from a file, we say that
it reads from the file.
When a program puts data into a file, we say that
it writes to the file.
To read or write to a file, we create a stream object,
and connect it to the file.
Text Files
Data in a file can either be text or binary.
Everything in a text file appears as readable
characters. You can look at the file with a text
editor, such as notepad.
Text files are sometimes referred to as Formatted files.
This semester we will only deal with text files.
The fstream classes
We use objects of the ifstream class to read from
a file, and objects of the ofstream class to write to
a file.
These classes are defined in <fstream>. To use them
we must write
#include <fstream>
ifstream Operations
>>
get ( )
getline( )
ignore( )
stream extraction operator
extract one character
read a line of data into a string
skip a character
these ought to look familiar, they are the same
functions we use on standard In and standard Out.
Example Code
ifstream fileData (“c:\\thefile.txt”);
char a;
string s;
int n;
a = fileData.get( );
fileData.ignore( );
getline(fileData, s);
fileData >> n;
// pass over newline
Declaring A Stream
To use a stream object, it must first be declared
ifstream inStream;
ofstream outStream;
Stream variables
A stream object is like any other variable, but
there are some important exceptions:
You cannot assign a value to a stream variable
If you pass a stream variable as a parameter, you
must pass it by reference.
Connecting a Stream to a File
ifstream inputStream;
inputStream.open (“theData.txt”);
to program
inputStream
theData.txt
Widget
123V89001 12.95
The preferred method for opening a file is to supply
the path when the stream object is created, like this
ifstream inputStream (“theData.txt”);
Paths
ifstream inputStream;
inputStream.open (“theData.txt”);
if no path is specified, the file is assumed
to be in the same directory as the program
that is executing.
When you code a \ in a pathname, you must
write \\. Why?
inputStream.open (“c:\\theData.txt”);
More on Paths and
Visual C++ Express
You need the file in here when
testing your code from the
Console.
If this is the folder
for your project
You need the file here when
testing your code within C++
Visual Express Edition
Reading From a Text File
To read data from a text file, use the stream
extraction operator, just as you would use it to read
from the keyboard.
string description;
string partNumber;
double price;
// no spaces
// no spaces
ifstream inputStream;
inputStream.open (“theData.txt”);
…
inputStream >> description >> partNumber >> price;
…
Reading From a Text File
If the data contains spaces, e.g. a person’s name
then you must use the getline function from <string>
string name;
ifstream inputStream;
inputStream.open (“theData.txt”);
…
getline(inputStream, name);
…
Type Safe I/O
In the C programming language, input and output
are done with very different libraries than those
used in C++ (Although you can still use the C I/O
libraries in C++ if you want to).
One of the advantages to using the new C++ libraries
is that C++ I/O is typesafe. The << and >> operators are
overloaded to do the correct thing for all of the standard
data types.
These operators can also be overloaded for user defined
data types.
in the file, this is
character data.
inputStream
theData.txt
Widget
123V89001 12.95
double price;
inputStream >> price;
Data is read from the file and converted into
the appropriate data type.
price
convert from
…111000011010…
character to double
Writing to a Text File
Use the stream insertion operator to write to a text file,
just as if you were writing to the display.
ofstream outputStream;
outputStream.open (“theData.txt”);
…
outputStream << price;
Opening an Output file
If the named file does not exist, the file is created.
If the named file already exists, it is opened, and
the contents of the file are discarded, by default.
Formatting the Output
Most of the time, when we write data to a file, it is
with the idea in mind that the data will be read in
from this or some other program.
It is up to the programmer to format the data in the
output file, so that it can later be read in a meaningful
way.
Example
int a = 5;
int b = 15;
int c = 239;
ofstream myOutputStream (“mydata.txt”);
myOutputStream << a << b << c;
515239
What happens when you try to read this file?
int a = 5;
int b = 15;
int c = 239;
ofstream myOutputStream (“mydata.txt”);
myOutputStream << a << “ “
<< b << “ “
<< c;
add white space to
separate the fields!
Closing the File
It is good programming practice to close a file
as soon as you are done using it.
myOutputStream.close ( );
Although a file is closed automatically when a
program ends normally, it is not closed if an error
occurs and the program terminates abnormally.
If the file is not closed, all of the data written to
the file is lost!
Mode Bits
When a file is opened, you can supply bits that further
define the file. These mode bits are defined in the ios
class. The ios class contains a number of important
constants we use in file I/O.
ios::in
ios::out
ios::app
ios::trunc
open the file for reading, the default for ifstream
open the file for writing, the default for ofstream
open the file for appending. All data is written at the end of the file
open the file and discard contents, the default for ofstream
ios::binary
open the file for binary content, Note there is no ios::text
which is the default
Example
#include <fstream>
using std::ofstream;
using std::ios;
ofstream myOutputStream (“TheData.txt”, ios::app);
…
Stream States
Objects of all of the stream classes have a state that
expresses the condition of the stream..
The stream classes provide functions to query the
stream’s state.
good( )
eof( )
fail( )
bad( )
Everything’s fine
An input operation tried to read beyond the end of the file
An input operation failed to read the expected character,
or an output operation failed to generate the desired characters
Indicates the loss of integrity of the underlying input or output sequence
Checking that a File Opened
In C++, errors are not reported unless the programmer
explicitly asks. For example, your program could call
for a file to be opened and then read data from the file.
If the file does not exist, no error is reported and you
think that everything worked fine!
ifstream myInputStream;
myInputStream.open (“someData.txt”);
if (myInputStream.fail( ))
{
cout << “Could not open file”;
}
else
{
…
check the state of the
stream here…
We could also write
if (!myInputStream)
{
Because I/O is subject to so many errors,
it is good programming practice to check
the state of the stream after
every I/O operation!
Writing a loop that reads until end of file
try to open
the file
did it open
?
yes
is the end
of file flag
set
?
no
no
print an error
message and
quit
is the eof
flag set
?
yes
continue with the
rest of your
program
no
read a piece
of data
was the
read good
?
yes
yes
no
was the eof
flag set
?
no
process the data
display an error
message and quit
We can read and test the state of the stream using
the expression
while (myFile >> theData)
theFile.open("c:\\theFile02.txt");
while (theFile >> theData)
{
cout << "\nSuccessfully read in the value " << theData;
}
// dropped out, so read failed, see if it is eof or an error
if (!theFile.eof( ) )
{
cout << "\nCould not read an integer - bad data in the file.";
}
else
{
cout << "\nReached the end of the file.";
}
File Names as Input
string fileName;
cout << “Enter in a file name: “;
cin >> fileName;
ifstream myData (fileName);
…
Formatting Flags
Formatting flags are defined in the ios class.
Stream classes have a member function,
setf( flag ) that sets these formatting flags.
left
right
dec
hex
oct
showpoint
scientific
fixed
left align output
right align output
output as decimal
output as hexadecimal
output as octal (base 8)
show decimal point on output
output in exponential format
output in fixed format (not scientific)
not set
set
set
not set
not set
not set
not set
not set
You can combine flags with the | operator
myStream.setf (ios::fixed | ios::showpoint);
A flag remains set until it is unset.
myStream.unsetf (ios::fixed);
Stream Manipulators
Stream manipulators go directly into the stream.
They are inserted using the stream insertion operator
dec
hex
oct
endl
setw (w)
setprecision (n);
setiosflags (flags);
setfill (fillChar);
myStream << setw (5) << theData;
Side Effects
You don’t want a function to have an unwanted side effect.
One example would be setting I/O flags in a function and
leaving them that way when you exit the function.
The function flags returns a long data type that
contains the settings of all of the I/O flags.
long myFlags = myStream.flags ( );
…
without an argument the
function returns the flags.
myStream.flags (myFlags);
with an argument, the flags are restored
to those set in the parameter.
File Pointers
Streams have pointers associated with them
get pointer
put pointer
points to the place next character will be read from
points to where the next character will be written
tellg( )
tellp ( )
returns current get pointer
returns current put pointer
seekg ( )
seekp ( )
positions get pointer
positions put pointer
seekp (15);
move 15 bytes from start of file
seekp (-10, ios::end);
move -10 bytes from end of file
seekg (6, ios::cur);
move 6 bytes from current position
Binary I/O
We will not do any binary I/O in this course.
Data is written to the output device exactly as it
Is stored in memory.
Binary I/O is done with the functions
* read( )
* write( )
The parameters are the address of the data buffer
and the number of bytes to read or write.
The address must be cast to a char*
Persistence
We say that a class has persistence when it is possible
for an object of that class to exist outside of the life
of the program.
We accomplish this by having the object save itself
(i.e. its data) to a file, and then make it so the object
can read itself (its data) back in from a file.