Converting this program from 1 function to a modular, multi-function program?

71 Views Asked by At

I am very new to C++ and have a program which I included below.

The program I am working on reads text from an input file and counts the number of words and number of occurrences of each letter in the text and then prints the results. My program is working fine but the problem is all code is written in the main function and I need to break it up into a couple more functions to make the program modular, but I am unsure of how to go about doing this.

I am sure this is pretty simple but I'm not sure where to start. I was thinking of implementing two void functions, one for reading / interpreting what is read from the data file and another that displays the results; and then call them both in the main function, but I'm not sure what to take as arguments for those functions.

int main()
{
    // Declaring variables
    char c; // char that will store letters of alphabet found in the data file
    int count[26] = {0}; // array that will store the # of occurences of each letter
    int words = 1; // int that will store the # of words
    string s; // declaring string found in data file

    // Opening input file stream
    ifstream in;
    in.open("word_data.txt");

    // Reading text from the data file
    getline(in, s);
    //cout << s << endl;

    // If input file fails to open, displays an error message
    if (in.fail())
    {
        cout << "Input file did not open correctly" << endl;
    }


    // For loop for interpreting what is read from the data file
    for (int i = 0; i < s.length(); i++) {

        // Increment word count if new line or space is found
        if (s[i] == ' ' || s[i] == '\n')
            words++;

        //If upper case letter is found, convert to lower case.
        if (s[i] >= 'A' && s[i] <= 'Z')
            s[i] = (tolower(s[i]));

        //If the letters are found, increment the counter for each letter.
        if (s[i] >= 'a' && s[i] <= 'z')
            count[s[i] - 97]++;
    }


    // Display the words count
    cout << words << " words" << endl;

    // Display the count of each letter
    for (int i = 0; i < 26; i++) {
        if (count[i] != 0) {
            c = i + 97;
            cout << count[i] << " " << c << endl;
        }
    }
         
    // Always close opened files
    in.close();

    return 0;

}
1

There are 1 best solutions below

0
Top-Master On

I would rewrite it like:

class FileReader {
public:
    FileReader() {
        // Any init logic goes here...
    }
    ~FileReader() {
        // Always close opened files.
        in.close();
    }

    void open(std::string &filePath) {
        in.open(filePath);
    }

    std::string readLine() {
        std::string s;
        getline(in, s);
        return s;
    }

    bool hasErrors() const { // remove const if you get compile-error here.
        return in.fail();
    }

private:
    ifstream in;
};

class LetterCounter {
public:
    void process(std::string &s) {
        // For loop for interpreting what is read from the data file
        for (int i = 0; i < s.length(); i++) {
            // Increment word count if new line or space is found
            if (s[i] == ' ' || s[i] == '\n')
                words++;

            //If upper case letter is found, convert to lower case.
            if (s[i] >= 'A' && s[i] <= 'Z')
                s[i] = (tolower(s[i]));

            //If the letters are found, increment the counter for each letter.
            if (s[i] >= 'a' && s[i] <= 'z')
                count[s[i] - 97]++;
        }
    }

    void logResult() {
        char c; // char that will store letters of alphabet found in the data file.

        // Display the words count
        cout << words << " words" << endl;

        // Display the count of each letter
        for (int i = 0; i < 26; i++) {
            if (count[i] != 0) {
                c = i + 97;
                cout << count[i] << " " << c << endl;
            }
        }
    }

private:
    int count[26] = {0}; // array that will store the # of occurences of each letter
    int words = 1; // int that will store the # of words
};

int main()
{
    // Opening input file stream.
    FileReader reader;
    reader.open("word_data.txt");

    // Reading text from the data file.
    std::string s = reader.readLine();

    // If input file fails to open, displays an error message
    if (reader.hasErrors()) {
        cout << "Input file did not open correctly" << endl;
        return -1;
    }

    LetterCounter counter;
    counter.process(s);
    // Display word and letter count.
    counter.logResult();
    
    return 0;
}

Note that I did write without testing (excuse any mistake),
but this should give you a general idea how it should be.