1

I am currently working on a small project in C++ and am a bit confused at the moment. I need to read a certain amount of words in a line that is taken from a file using ifstream in(). The problem with it right now is the fact that it keeps ignoring spaces. I need to count the amount of spaces within the file to calculate the number of words. Is there anyway to have in() not ignore the white space?

ifstream in("input.txt");       
ofstream out("output.txt");

while(in.is_open() && in.good() && out.is_open())
{   
    in >> temp;
    cout << tokencount(temp) << endl;
}
Oleg Svechkarenko
  • 2,340
  • 22
  • 28
Magical Toast
  • 47
  • 1
  • 8

3 Answers3

3

To count the number of spaces in a file:

std::ifstream inFile("input.txt");
std::istreambuf_iterator<char> it (inFile), end;
int numSpaces = std::count(it, end, ' ');

To count the number of whitespace characters in a file:

std::ifstream inFile("input.txt");
std::istreambuf_iterator<char> it (inFile), end;
int numWS = std::count_if(it, end, (int(*)(int))std::isspace);

As an alternative, instead of counting spaces, you could count words.

std::ifstream inFile("foo.txt);
std::istream_iterator<std::string> it(inFile), end;
int numWords = std::distance(it, end);
Robᵩ
  • 143,876
  • 16
  • 205
  • 276
  • +1 for the istreambuf_iterator trick. I was wondering if there was something along those lines that would let you do it with a single iterator for the whole file :) – Nathan Monteleone Jan 25 '13 at 19:14
2

Here's how I'd do it:

std::ifstream fs("input.txt");
std::string line;
while (std::getline(fs, line)) {
    int numSpaces = std::count(line.begin(), line.end(), ' ');
}

In general, if I have to do something for every line of a file, I find std::getline to be the least finicky way of doing it. If I need stream operators from there I'll end up making a stringstream out of just that line. It's far from the most efficient way of doing things but I'm usually more concerned with getting it right and moving on with life for this sort of thing.

Nathan Monteleone
  • 5,110
  • 26
  • 42
1

You can use count with an istreambuf_iterator:

ifstream fs("input.txt");

int num_spaces = count(istreambuf_iterator<unsigned char>(fs),
                       istreambuf_iterator<unsigned char>(),
                       ' ');

edit

Originally my answer used istream_iterator, however as @Robᵩ pointed out it doesn't work.

istream_iterator will iterate over a stream, but assume whitespace formatting and skip over it. My example above but using istream_iterator returned the result zero, as the iterator skipped whitespace and then I asked it to count the spaces that were left.

istreambuf_iterator however takes one raw character at a time, no skipping.

See istreambuf_iterator vs istream_iterator for more info.

Community
  • 1
  • 1
Peter Wood
  • 21,348
  • 4
  • 53
  • 90