Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Duplicate entry while reading from ifstream into vector

Reply
Thread Tools

Duplicate entry while reading from ifstream into vector

 
 
steve.cpp@gmail.com
Guest
Posts: n/a
 
      12-28-2008
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: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
 
Reply With Quote
 
 
 
 
alfps
Guest
Posts: n/a
 
      12-28-2008
On 28 Des, 03:42, steve....@gmail.com wrote:
>
> * * * * 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
 
Reply With Quote
 
 
 
 
James Kanze
Guest
Posts: n/a
 
      12-28-2008
On Dec 28, 4:40 am, alfps <alf.p.steinb...@gmail.com> wrote:
> On 28 Des, 03:42, steve....@gmail.com wrote:
> > 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!),


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.

> e.g.


> 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.)

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Initializing vector<vector<int> > and other vector questions... pmatos C++ 6 04-26-2007 05:39 PM
identifying end of line while reading data from an ifstream omariqbalnaru C++ 3 11-23-2006 09:34 PM
Free memory allocate by a STL vector, vector of vector, map of vector Allerdyce.John@gmail.com C++ 8 02-18-2006 12:48 AM
Reading ints from ifstream to a vector Dr. Len C++ 4 07-21-2004 04:47 PM
Reading Blank Lines into StringTokens into Vector Array Row Java 0 04-14-2004 07:12 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57