Mitchell Schwitzer
Mitchell Schwitzer

Reputation: 98

C++: Counting function only counts first line

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

Answers (3)

Devolus
Devolus

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

Sebastian Redl
Sebastian Redl

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

aardvarkk
aardvarkk

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

Related Questions