Reputation: 98
I have a problem trying to count words inside of a vector. A vector holds every line from a file as an object. v[0] is the first line, v[1] is the second line, so on.
For my countWords() function, it only works for counting v[0]. Any object past that is ignored or missed some how. Any ideas? Thanks in advance.
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int countWords(vector<string> v)
{
stringstream ss;
string word;
int count = 0;
for(int i = 0; i < v.size(); i++) {
ss.str(v[i]);
while (ss >> word)
count++;
}
return count;
}
void readFile(string filename,vector<string> &v)
{
fstream file;
string line;
file.open(filename,ios::in);
while(getline(file,line)) { //Reads the file line by line ...
if(line == "") //... ignoring any empty lines ...
continue;
v.push_back(line); //... and puts them into our vector.
}
file.close();
}
int main(int argc,char* argv[])
{
if (argc != 2) { //Terminate unless the user enters -ONE- entry.
cout << "Usage: " << argv[0] << " <filename>" << endl;
exit(1);
}
string filename = argv[1];
vector<string> fileContents;
readFile(filename,fileContents);
cout << countWords(fileContents) << endl;
}
Upvotes: 3
Views: 173
Reputation: 22094
Before you reuse stringstream you must do
ss.clear();
after your while loop.
You could also declare it inside the for()
loop, but then it would be reinitialized again. For readabillity, this might be better. Performancewise it could make a difference.
Upvotes: 4
Reputation: 72062
I bet ss
goes into an error state when you've exhausted it for the first time and doesn't reset just because you call str
.
Declare ss
inside the for loop and pass the string directly to the constructor. This avoids such problems.
In general, you have the bad habit of declaring your variables in a bunch instead of closest to where you need them, and not using constructors. For example, you could pass the filename to fstream
's constructor instead of calling open
. And you could use ifstream
so you don't need the second argument.
Upvotes: 1
Reputation: 15996
As an alternative to RichieHindle's answer, this works too. Just have the stringstream scope local to the for loop and it will reset properly.
int countWords(vector<string> v)
{
string word;
int count = 0;
for(int i = 0; i < v.size(); i++) {
stringstream ss(v[i]);
while (ss >> word)
count++;
}
return count;
}
Upvotes: 6