Duplicate entry while reading from ifstream into vector

S

steve.cpp

Hi,
I'm new at C++, I'm using Stroustrup's book to learn and trying to
finish an exercise on page 505 (#3) and it works except that I am
getting an duplicate string read into a vector and can't figure out
the reason. This is not a homework assignment, I want to learn C++ as
a skill:

#include <fstream>
using std::fstream;
using std::ifstream;
using std::eek:fstream;

#include <iostream>
using std::cout;
using std::endl;
using std::getline;
using std::ios;

#include <string>
using std::string;

#include <vector>
using std::vector;

int main( int argc, char *argv[] )
{
if(argc != 2) {
cout << "Incorrect number of arguments, should be two,
turkey." << endl;
exit(1);
}

ifstream readFile( argv[1], ios::in );
cout << "argv[1] is " << argv[1] << endl << endl;
if( !readFile) {
cout << "Can't open " << argv[1] << ", exiting." <<
endl;
return 0;
}
else
cout << argv[1] << " opened for reading." << endl <<
endl;

string temp;
vector< string > lw;
//while( readFile && !readFile.eof() ) {
while( !readFile.fail() ) {
readFile >> temp;
cout << "temp is: " << temp << endl;
lw.push_back(temp);
}
readFile.close();
cout << endl;
cout << "Here's the vector." << endl;

for( vector<string>::iterator p = lw.begin(); p != lw.end(); +
+p)
cout << *p << endl;

return 0;
}

When I execute the program, no matter which text file I use, the last
word in the file is duplicated (there's not a duplicated string at the
end of the file), such as if the last word is "dawn," it appears twice
when I output the strings in the while loop and also with the
iterator.

I've tried changing the while loop to use different tests to determine
the end of the file but I get a duplicate line each time.

When the end of file is reached, the while loop should terminate and
not call push_back() again but for some reason, it calls it twice.

I've tried to use an istringstream as well but always end up with the
last word in the file duplicated.

I apologize ahead of time if this is a basic issue but I can't
eliminate the duplicate entry.

Steve
 
A

alfps

        string temp;
        vector< string > lw;
        //while( readFile && !readFile.eof() ) {
        while( !readFile.fail() ) {
                readFile >> temp;
                cout << "temp is: " << temp << endl;
                lw.push_back(temp);
        }

Consider what happens when the input operation (the >>) fails. 'temp'
is not changed. The code proceeds, using the old value, to output
"temp is:" and then to add that old value at the end of the vector.

The idiomatic way to do this relies on implicit conversion to bool:

while( readFile >> temp ) ...

I think that if I were to use iostreams I'd write it more explicitly
(I suspect many people using the idiomatic way don't understand what
it means!), e.g.

for( ;; )
{
readFile >> temp;
if( readFile.fail() ) { break; }
...
}

Then the ugliness of the code reflects the ugliness of the
iostream. :)


Cheers & hth.,

- Alf
 
J

James Kanze

Consider what happens when the input operation (the >>) fails.
'temp' is not changed. The code proceeds, using the old value,
to output "temp is:" and then to add that old value at the end
of the vector.
The idiomatic way to do this relies on implicit conversion to
bool:
while( readFile >> temp ) ...
I think that if I were to use iostreams I'd write it more
explicitly (I suspect many people using the idiomatic way
don't understand what it means!),

You might be right. One of the advantages of the idiomatic way
is that it works, even if you don't understand it.

Of course, some people who do understand it still use it,
precisely because it is the idiomatic way.
for( ;; )
{
readFile >> temp;
if( readFile.fail() ) { break; }
...
}

That's even worse. I do sort of like:

for ( readFile >> temp ; readFile ; readFile >> temp ) ...

But in the end, the advantage of being idiomatic outweighs the
other advantages.
Then the ugliness of the code reflects the ugliness of the
iostream. :)

The problem is that nothing better has been proposed. (I/O is a
difficult problem, because it involves side effects which may
fail.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top