File Input
Input streams
Having created and opened your file for input as in the
earlier discussion, your program can now read data from the file in the
same way it read data from cin -- using the stream extraction operator >>.
int int1;
string s1;
inStream >> int1;
inStream >> s1;
The function getline( ) may also be used with streams to read
strings that include whitespace.
getline( inStream, s1 );
A common I/O Pitfall
Recall that the extraction operator >> has two important
characteristics
- It skips leading whitespace (including the newline character)
- It stops when it sees the next whitespace, but leaves that whitespace
(including the newline) for the next input
When all the data in the file is the same type (numeric or text),
simply using operator >> is best and easiest way.
For example, if our input file looked like this
5 42 77 63
22 86
47
we could write code like this to read all the integers
for (int i = 0; i < 7; i++)
{
int value;
inStream >> value;
// do something with value
}
or if the file contained all strings
now is the time for all
good men
to
come to
the aid of their
party
we could write this code
for (int i = 0; i < 16; i++)
{
string word;
inStream >> word;
// do something with word
}
In fact, as long we are reading each piece of data (surrounded by
whitespace) as a single entity, then opeator >> works just fine.
When using getline( ) and the extraction operator ( >> ) together to perform
input, you must use extreme care to read the stream (user input or input file) properly.
Consider the following code
int age;
string name;
cout << "Input your age and first name";
cin >> age;
getline( cin, name );
If the user types
42
Bob Smith
the result will not be what you expect and not what you want.
The variable age will indeed contain the value 42, but
name will be empty.
The problem is two-fold
- The statement cin >> age; does not read in the newline character
at the end of the first input line. It just reads 42.
- getline(cin, name ); stops reading when it sees a newline character
These two behaviors result in getline(cin, name); reading no characters
at all and therefore name is empty.
The solution is to read and discard the newline character before using
getline(). This is accomplished with the function cin.ignore().
The cin.ignore() function can be used in several ways. For our purposes,
we can use cin.ignore( ); to read and discard the next character (which should
be the newline character) or cin.ignore( 1000, '\n'); which reads and discards
the next 1000 characters up to and including the first newline character it sees.
The ignore() function also works with file streams (ifstream) objects.
Checking for end-of-file
There are two basic ways of checking for end-of-file (eof) when reading
from a file. Incorrect code may have problems when the input file
contains "blank lines" at the end. Incorrect code will appear to read
the last line of input twice.
The general approach (see text page 513) is to use a "priming read"
and check for eof as a condition of a 'while loop'.
string name;
inStream >> name;
while( !inStream.eof() )
{
// do something with name
// read the next name
inStream >> name;
}
An alternative that works especially well when getline() is not involved
is the following code. This code make use of the fact that using operator >>
returns a boolean value that tells us if the read was successful.
string name;
while( inStream >> name )
{
// do something with name
}
Last Modified: Monday, 28-Aug-2006 10:15:54 EDT