Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

LtRammstein

macrumors 6502a
Original poster
Jun 20, 2006
570
0
Denver, CO
Another problem. I am creating this program that reads in a text file and counts the words and how many times it occurs in there using the map class. Well, I got it mostly written, and I decided to test to see if it reads in the file, well I ran into a snag. While debugging, the string functions (they are in bold), are not doing their job or I'm not using them right. Can you all be check to see where I'm going wrong?

The input file I use is the Declaration of Independence. I can put up the file itself if requested.

Code:
#include <iostream>
#include <map>
#include <string>
#include <fstream>
#include <cctype>
 
#define MAX 64
 
using namespace std;

class WordCount {
private:
    map<string, int> a_map;
    string newWord, currentLine;
	size_t nextWord;
    char filename[MAX];
public:    
    WordCount(char filename[]) {
        ifstream infile(filename);
    
        while (!infile.eof()) { 
			getline(infile, currentLine);

			size_t start;
			size_t end = 0;
			while(!currentLine.empty()) {
				start = currentLine.find_first_not_of(" ");
				end = currentLine.find_first_of(" ");
				newWord = currentLine.substr(start, end);
				for(int i = 0; newWord[i] != '\0'; i++) {
					if(!isalpha(newWord[i])) 
						newWord[i] = '\0'; 

					if(isupper(newWord[i])) 
						newWord[i] = tolower(newWord[i]); 
				}
				wordCounter(newWord);
			}
        }
    }
 
    void wordCounter(string newWord) { 
        a_map.find(newWord);

		if(a_map[newWord] == 0)
			a_map[newWord] = 1;
		else
			a_map[newWord] += 1;
    } 
 
    void sortList() {
		

    }
 
    void displayAll() { 
		for(map<string,int>::iterator itr = a_map.begin(); itr != a_map.end() ; ++itr){
			cout << itr->first << " " << itr->second << endl;
		}
    } 
    
    
};
 
int main () {
    //char fileName[MAX];
	//cout << "Enter document name: ";
	//cin >> fileName;

	WordCount count("declaration.txt");
	count.displayAll();
    return 0;
}
 

bbarnhart

macrumors 6502a
Jan 16, 2002
824
1
Code:
void wordCounter(string newWord) { 
        a_map.find(newWord);

		if(a_map[newWord] == 0)
			a_map[newWord] = 1;
		else
			a_map[newWord] += 1;
    }

I don't understand what a_map.find(newWord) is doing. I would think that you would need the iterator return value.

Code:
typedef map<string, int> STRING_INT;

STRING_INT::iterator it = a_map.find(newWord);

if (it == a_map.end())
  a_map[newWord] = 1; // a_map.insert(STRING_INT::value_type(newWord, 1)); ?
else
  a_map[newWord]++; // a_map[newWord] = a_map[newWord] + 1 ?

The "bonus" code behind the comment is another possible solution. I didn't test this and it's been a while since I've used the STL.

Also, you might need to write your own function class for the comparion

Code:
typedef map<string,int, str_comp> STRING_INT;

Don't remember how to write a comparison function class, but I've written a bunch before for maps with strings as keys
 

notjustjay

macrumors 603
Sep 19, 2003
6,056
167
Canada, eh?
One nice thing about accessing maps by key is that you don't actually need to do the check to see if it previously existed.

i.e. if x is a map<string, int> and I go

x["hello"] = 1;

It doesn't matter whether or not there was already an element with key "hello" in the map -- if there was, then the old element is updated, if there wasn't, then there will be after the call is done.

In some cases this is bad, but in your case, this is what you want since if it didn't exist before you'll just be adding it anyway. So your existence check is a bit redundant (not to mention the find() is incorrectly handled, as was already mentioned)
 

bbarnhart

macrumors 6502a
Jan 16, 2002
824
1
In some cases this is bad, but in your case, this is what you want since if it didn't exist before you'll just be adding it anyway. So your existence check is a bit redundant

I would think that a check would be necessary because the user is trying to increment a counter for each occurrence of a word. The check would be, has this word occurred before? If not, set it equal to one. I don't think the STL will default the int from map<string, int> to zero. It might.
 

LtRammstein

macrumors 6502a
Original poster
Jun 20, 2006
570
0
Denver, CO
Sorry guys. I got it to work. What I was doing was really difficult and retarded. I talked to a friend of mine, and he just said use the infile >> newWord. I from there got rid of the wordCounter() because a map does the check anyways.

Thanks for the input!
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.