-4

I am having problems with my program. Basically it finds the word count of a text file, the most and least repeated word, and have the user find a word. My problem is that when I find a words, it skips the indices of the repeated words. For example, if a text file has the words:

one two one one three five

and the user searches for "three", it will output that the index is 2. It skips over the repeated words. Why is that?

Here is my code:

int main() {
    int counts[ARRAY_SIZE] = { 0 };
    string words[ARRAY_SIZE];
    ifstream inFile;
    string filename, searchWord, lowerCase;
    int wordCount = 0, totalWords = 0, index = 0;
    int result, mostIndex, leastIndex;
    cout << "Enter a text file: ";
    cin >> filename;
    inFile.open(filename);
    while (!inFile.is_open()) {

        if (filename == "q") {
            inFile.close();
            return 0;
        }
        else if (inFile.is_open()) {
            cout << filename << " is open";
        }
        else {
            cout << "Enter a valid file or type \"q\".";
        }
        cout << "The file you enetered is not valid, please enter a valid file or type \"q\" to quit.";
        cin >> filename;
        inFile.open(filename);
    }
    while (!inFile.eof()) {
        while (inFile >> lowerCase) {
            wordCount++;
            lowerCase = convertCase(lowerCase);
            result = search(words, lowerCase, totalWords);
            if (result == NOT_FOUND) {
                words[totalWords] = lowerCase; // lowerCase is a new word, so add it to the array,
                counts[totalWords] = 1;      //  and set it's count to 1.
                totalWords++;
            }
            else {
                counts[result]++; // The word was found, so increment the times we've seen it.
            }
        }

        cout << endl << "Total words: " << wordCount << endl;
        cout << "Search a word: ";
        cin >> searchWord;
        index = search(words, searchWord, totalWords);
        if (index == NOT_FOUND) {
            cout << "\"" << searchWord << "\"" << " was not found." << endl;
        }
        else {
            cout << endl << "the word " << "\"" << searchWord << "\"" << " is found on at index " << index << endl;
        }
        mostIndex = findIndexOfMost(counts, totalWords);
        leastIndex = findIndexOfLeast(counts, totalWords);
        cout << "The most repeated word is \"" << words[mostIndex] << "\" and was found " << counts[mostIndex] << " time(s)." << endl;
        cout << "The least repeated word is \"" << words[leastIndex] << "\" and was found " << counts[leastIndex] << " time(s)." << endl;
    }
    system("pause");
    return 0;
}


string convertCase(string word){
    for (int i = 0; i < word.length(); i++) {
        word[i] = tolower(word[i]);
    }
    return word;
}

int search(string words[], string searchWord, int totalWords){

    int index = NOT_FOUND;
    for (int i = 0; i < totalWords; i++){
        if (words[i] == searchWord){
            index = i;
            break;
        }
    }
    return index;
}

int findIndexOfMost(int counts[], int totalWords){
    int most; // assume most is first count.
    int index = 0, i;
    most = counts[index];

    for (i = 0; i < totalWords; i++)
    {
        if (counts[i] > most){
            most = counts[i];
            index = i;
        }
    }

    return index;
}

int findIndexOfLeast(int counts[], int totalWords) {
    int least, index = 0, i;
    least = counts[index];

    for (i = 0; i < totalWords; i++)
    {
        if (counts[i] < least) {
            least = counts[i];
            index = i;
        }
    }

    return index;
}
leon9692
  • 3
  • 2
  • 1
    Have you debugged it? I think it should be easy to spot once you step through it... – wkl Jun 08 '17 at 06:25
  • 1
    *Why is that?* -- Debugging is part and parcel of learning how to write a program. You can't just write code, see that it doesn't work, post on SO that it "doesn't work" and "why?", and sit back and wait for an answer. Where does the program flow, logic, variable values, etc. go against your plan (since you wrote the code)? – PaulMcKenzie Jun 08 '17 at 06:26
  • 1
    Oh sure you can! It's just grotesquely inefficient, and a good outcome is far, far less likely than debugging. It's almost as bad as `while (!inFile.eof())`. You don't want to do that, Leon. Read this question and answer to find out why: https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong – user4581301 Jun 08 '17 at 06:33
  • Note: Usage of a `std::map` where `word_info` is a struct that holds a count and list of indices of the word makes this a much easier job. – PaulMcKenzie Jun 08 '17 at 07:03

1 Answers1

2

I agree with the comments on your post, but I did find your error rather quickly. I highly suggest you try the debugger in the future to follow the variables you care about and see what is happening and how they are updating, when they're not updating as you think they would. Even simply printing your array words would show you the problem.

You're only adding words to the words array when they haven't been found yet, so when you search through words, you're searching through the unique words.

    if (result == NOT_FOUND) {
        words[totalWords] = lowerCase; // lowerCase is a new word, so add it to the array,
        counts[totalWords] = 1;      //  and set it's count to 1.
        totalWords++;
    }
    else {
        counts[result]++; // The word was found, so increment the times we've seen it.
    }

For the file

one two one one three five

your variable words would hold

one two three five

so if you searched for 'three' in words you would get the index 2, even though it's the fifth word in your file, so you want the index 4.

alkasm
  • 17,991
  • 3
  • 60
  • 78