【问题标题】:Converting this program from 1 function to a modular, multi-function program?将此程序从 1 个功能转换为模块化的多功能程序?
【发布时间】:2021-09-24 14:27:47
【问题描述】:

我对 C++ 非常陌生,并且有一个程序,我将其包含在下面。

我正在处理的程序从输入文件中读取文本并计算文本中每个字母的单词数和出现次数,然后打印结果。我的程序运行良好,但问题是所有代码都编写在主函数中,我需要将其分解为更多函数以使程序模块化,但我不确定如何去做。

我相信这很简单,但我不知道从哪里开始。我正在考虑实现两个 void 函数,一个用于读取/解释从数据文件中读取的内容,另一个用于显示结果;然后在主函数中调用它们,但我不确定这些函数的参数是什么。

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;

}

【问题讨论】:

  • 这样想:函数(理论上)都应该在同一个“级别”上工作,并专注于做特定的事情。所以你有读入文件的代码,你有迭代文件中行的代码,你有处理一行的代码,你有显示结果的代码。任何给定的函数都会接受它需要的参数,然后返回一些可用的东西。
  • 我想说你可以先试试 not 在开头声明所有变量。 (顺便说一句,你已经在 for 循环中做了)
  • 不要预先声明所有变量。在需要它们的地方声明它们,并尽可能缩小它们的范围。在您拥有它的两个地方将 97 替换为 'a'。您在其他地方都使用了这些字符,不知道为什么这两个地方不同。考虑创建一个函数来更新特定字符的计数,并创建另一个函数来打印计数。这不是一个很大的计划,在我看来,做更多的事情并不一定有意义。
  • 您可以编写以后可以在其他项目中使用的函数。例如std::string readFile(std::string in) {}你可以使用getline并返回字符串s
  • 这里有个思路:写一个函数,接受一个字符串,返回字符串中的单词数。您可以编写另一个函数,该函数接受 std::map&lt;char, int&gt;&amp; 和字符串并读取字符串中的字符,更新 map

标签: c++ function modular-design


【解决方案1】:

我会像这样重写它:

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;
}

注意,我没有测试就写了(请原谅任何错误),
但这应该让您大致了解它应该是怎样的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-22
    • 2017-03-30
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 2020-11-02
    • 1970-01-01
    相关资源
    最近更新 更多