Trying to count words in a file, keep getting double

Started by
17 comments, last by Zahlman 19 years, 3 months ago
Ok. I'm making hangman. The program is supposed to choose a word at random from a file called "words.txt". The first step is to find out how many words are in the file, then resize an array to that size, fill it up with words from the file and then shuffle the order of the array (so the player won't get repeats during the same game). I don't know enough to know if that is an unduly convoluted set up (if it is go ahead and be honest). Either way though, the method I use to count the number of words always delivers twice the actual number of words. I could simply divide by two but looking at my code it is not apparent to me why it keeps counting twice the number of words and I'd really rather not have to compensate for bad code. So here it is, you have to make a .txt file called words.txt in the same directory. Obviously with some words in it.

#include <iostream>
#include <cstdlib>
#include <fstream>
using namespace std;

int getCount();
int countWords = 0;

int main()
{
     getCount();
     if(getCount()==1)
     {
          cout << "\n\tError: The file words.txt cannot be found.\n"
               << "\tPlease make sure that there is a file by that\n"
               << "\tname in the same directory as this program.\n\n\t";
          system("pause");
          return 1;
     }
     cout << countWords << endl;
     system("pause");
}

int getCount()
{    
     ifstream loadWords("words.txt");
     string word;

     if(!loadWords)
     {
          return 1;
     }
     
     while(!loadWords.eof())
     {
          loadWords >> word;
          countWords++;          
     }
     loadWords.close();
     return 0;
}

skulldrudgery--A tricky bit of toil
Advertisement
Why are you calling the function twice?

Quote: then resize an array to that size


Why not use a vector or a deque?

#include <iterator>#include <iostream>#include <fstream>#include <vector>int main(){   std::ifstream ifs("words.txt");   std::istream_iterator<std::string> ifs_begin(ifs);   std::istream_iterator<std::string> ifs_end;   std::vector<std::string> words(ifs_begin, ifs_end);   std::cout << words.size() << std::endl;}
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Quote:Original post by Fruny
Why are you calling the function twice?


Hehe, yep, that's the answer right there.

You see this little code right here?
getCount();


That calls getCount() once. You knew that.

However, see this bit below it?
if(getCount()==1)


This calls getCount() as well. Delete the first call and you're good to go.

-Greven

What Fruny is trying to point out are these lines:
     getCount();     if(getCount()==1)


You call getCount, the call it again, to see if it equals 1. What you want to do in the if statement is check againts countWords, not getCount(). That is why you have double -- you are calling it twice.

[Edited by - visage on January 7, 2005 10:13:32 PM]
I didn't notice that I was...
skulldrudgery--A tricky bit of toil
Funny - most people catch that kind of issue themselves ... Right after they hit "post".

I know it does for me.

Wholly

Quote:Original post by visage
What Fruny is trying to point out are these lines:
     getCount();     if(getCount()==1)


You call getCount, the call it again, to see if it equals 1. What you want to do in the if statement is check againts countWords, not getCount(). That is why you have double -- you are calling it twice.


Nah, he just needs to delete the first getCount() call. More elegant that way. Plus, the way you suggest wouldn't work anyway (well, OK, it would if you changed the "==1" to "==0" as well...). See the getCount() function? It retuns 0 on success and 1 on fail, which is what he is testing for.

D'oh!

Why does the if statement call it again? I thought it was asking if the value was 1.

Quote:Why not use a vector or a deque?

I didn't know how to, until about 30 secs ago. :D
skulldrudgery--A tricky bit of toil
Quote:Original post by skulldrudgery
Why does the if statement call it again? I thought it was asking if the value was 1.


It calls the function and checks ask if the return value is 1.

Quote:I didn't know how to, until about 30 secs ago. :D


Time to learn. [wink]

Incidentally, problems like this one is one of the reason why people recommend avoiding global variables: it was not obvious from the function's interface that it was stateful and would keep adding to the previously tallied word count.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Ok, crisis averted. It works now. This also explains an earlier problem I had where "Press any key to continue" from system("pause") also came up twice. I used to have it at the end of the getCount() function. Thanks for the replies!
skulldrudgery--A tricky bit of toil

This topic is closed to new replies.

Advertisement