Where did I go wrong coding in CPP to incrementally count the amount of times a word occurs in a text file?

113 Views Asked by At

EDIT: Code updated using tips from SO replies. I get no errors when compiling, the list prints empty. Quantities are not updating.

Original Post: This is for school and I can't seem to get it to increment the items. It opens the file successfully but then prints 0 for occurrences even though there are at minimum 1 for each item I enter in the menu. This isn't my entire code but it's the code for my class since I think that's likely where I went wrong. Additionally, my menu won't recognize invalid input even though the else portion of the if/else is there to catch it. It just enters an infinite loop of printing the menu. I am open to all feedback and/or links to resources better than Zybooks to teach me what I am missing here.

class ItemCounter {
private:
    map <string, int> itemFrequency;
    string inputFile = "CS210_Project_Three_Input_File.txt";
    string outputFile = "itemTracker.dat";
public:
    void loadInputFile() {
        ifstream file(inputFile);
        // OPEN conditions
        if (file.is_open()) {
            string itemName;
            while (getline(file, itemName)) {
                int itemQuantity = 0;
                // Update item count
                itemFrequency[itemName] += itemQuantity;

                // Exception check for string conversion
                try {
                    itemQuantity = stoi(itemName);
                }
                catch (const invalid_argument& e) {
                    cout << "Error: Invalid Entry Found in Input File." << endl;
                    continue;
                }
            }
            // Close open file
            file.close();
        }
        // Else statement if file won't open
        else {
            cout << "Error: Could Not Open Input File" << endl;
            cout << endl;
        }
    }
    // Function to save new data to external file
    void saveOutputFile() {
        ofstream file(outputFile);
        if (file.is_open()) {
            for (auto& item : itemFrequency) {
                file << item.first << " " << item.second << endl;
            }
            file.close();
        }
        else {
            cout << "Error: Could Not Open Output File - Data Not Saved" << endl;
            cout << endl;
        }
    }

    // Function to display item occurrences
    void displayItemCount(string itemName) {
        int count = itemFrequency[itemName];
        cout << "Total Item Occurances for " << itemName << ": " << count << endl;

    }

    //Function to count and display total item counts of whole list
    void displayTotals () {
        for (auto& item : itemFrequency) {
            cout << item.first << " " << item.second << endl;
        }
    }

    // Function to count items in the list and print as histogram
    void displayItemsHistogram() {
        for (auto& item : itemFrequency) {
            cout << item.first << " ";
            for (int i = 0; i < item.second; i++) {
                cout << "*";
            }
            cout << endl;
        }
    }
};
    // Function to save new data to external file
    void saveOutputFile() {
        ofstream file(outputFile);
        if (file.is_open()) {
            for (auto& item : itemFrequency) {
                file << item.first << " " << item.second << endl;
            }
            file.close();
        }
        else {
            cout << "Error: Could Not Open Output File - Data Not Saved" << endl;
            cout << endl;
        }
    }
};

int main() { 
    ItemCounter itemCounter;
    itemCounter.loadInputFile();
    itemCounter.saveOutputFile();
    int menuChoice = 0;

    while (menuChoice != 4) {
        cout << "Main Menu" << endl;
        cout << endl;
        cout << "1. Stuff" << endl;
        cout << "2. Stuff" << endl;
        cout << "3. Stuff" << endl;
        cout << "4. Exit" << endl;
        cout << "Please make a selection: ";
        cin >> menuChoice;
        cout << endl;

        if (menuChoice == 1) {
            string itemName;
            cout << "Enter search term: ";
            cin >> itemName;
            cout << "FIX ME:" << endl;
        }

        else if (menuChoice == 2) {
            cout << "FIX ME" << endl;
        }

        else if (menuChoice == 3) {
            cout << "FIX ME" << endl;
        }
            
        else if (menuChoice == 4) {
            cout << "Program Terminated" << endl;
        }
        else {
            cout << "Invalid Selection, try again." << endl;
        }
    }
    return 0;
}

Read in data from file errors

Display list from file quantity fails to update

1

There are 1 best solutions below

1
john cena On

Issue with counting occurrences:

In the loadInputFile() function, you are initializing itemQuantity without assigning any value to it before using it to increment itemFrequency[itemName]. This means that you are incrementing with an uninitialized value, leading to incorrect results.

To fix this, you should convert itemCountStr to an integer and assign it to itemQuantity before incrementing itemFrequency[itemName].

Replace the line:

int itemQuantity;

with:

int itemQuantity = stoi(itemCountStr);

Issue with invalid input handling:

In the while loop in main(), if the user enters an invalid selection (a value other than 1, 2, 3, or 4), the program should not continue to print the menu indefinitely.

To address this, you can add a break; statement in the else block to exit the loop.

Replace:

else {
    cout << "Invalid Selection, try again." << endl;
}

with:

else {
    cout << "Invalid Selection, try again." << endl;
    break;
}

With these modifications, the code should now correctly increment the item occurrences, and handle invalid input by breaking out of the menu loop when necessary.