#include <fstream>
using std::fstream;
using std::ifstream;
using std::ofstream;
#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
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
> 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:james...@gmail.com
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