【问题标题】:How do I read words from a file, assign them to an array and analyze its content?如何从文件中读取单词,将它们分配给数组并分析其内容?
【发布时间】:2019-12-15 14:56:39
【问题描述】:

我(一位教授鼓励在线研究以完成项目的学生)有一项任务,我必须分析文件的内容(某些单词的频率、总单词计数、最大和最小单词),但我遇到了困难甚至打开文件,以便程序可以说出单词。我试图只计算它读到的单词,但我什么也没得到。据我了解,该程序应该打开选定的 .txt 文件,逐字检查其内容并立即输出。

代码如下:

#include <iostream>
#include <string>
#include <cctype>
#include <fstream>
#include <sstream>

    string selected[100];
    //open selected file.
    ifstream file;
    file.open(story.c_str());
    string line;
    if (!file.good())
    {
        cout << "Problem with file!" << endl;
        return 1;
    }
    while (!file.eof())
    {
        getline(file, line);

        if (line.empty())
            continue;

        istringstream iss(line);

        for (string word; iss >> word;)
            cout << word << endl;

    ```




【问题讨论】:

  • 调用main()是未定义的行为
  • 您和要求最小化代码的人之间存在误解。请阅读并应用这个概念:minimal reproducible example
  • 我建议将代码(这与上面的 MRE 想法不矛盾)简化到只尝试从文本文件中读取的程度。这样您就可以避免与调用main() 相关的所有未知数。您知道main() 是始终启动程序的函数,不是吗?所以试着让main()从文件中读取一个单词,然后继续让事情变得更复杂。
  • 以上代码并不是一个完整的程序。相比之下,大多数“hello world”程序都是完整的,尽管很小。您可能希望先让一个简单的程序运行起来,然后添加功能让您更接近您需要的位置,直到出现问题 - 然后寻求帮助。
  • 我猜它甚至没有打开 .txt 因为它无法访问文件本身? (修正了那个位。)现在它逐字打印出文件(进度),但我不知道如何一次将它分配给一个 100 个字的数组,所以我可以使用其他代码位来分析它。 (在将它放入数组之前,我不需要更多解释,我很感激到目前为止的帮助!)

标签: c++ arrays visual-c++ file-manipulation


【解决方案1】:

因为附上的代码比较简单,这里就不做详细解释了。使用std::algorithm,每项任务都可以在单行中执行。

我们会将完整的源文件读入一个std::string。然后,我们定义一个std::vector 并用所有单词填充它。这些词是由一个超简单的正则表达式定义的。

使用std::map 的标准方法计算频率。

#include <fstream>
#include <string>
#include <iterator>
#include <vector>
#include <regex>
#include <iostream>
#include <algorithm>
#include <map>

// A word is something consiting of 1 or more letters
std::regex patternForWord{R"((\w+))"};

int main() {

    // Open file and check, if it could be opened
    if (std::ifstream sampleFile{ "r:\\sample.txt" }; sampleFile) {

        // Read the complete File into a std::string
        std::string wholeFile(std::istreambuf_iterator<char>(sampleFile), {});

        // Put all words from the whole file into a vector
        std::vector<std::string> words(std::sregex_token_iterator(wholeFile.begin(), wholeFile.end(), patternForWord, 1), {});

        // Get the longest and shortest word
        const auto [min, max] = std::minmax_element(words.begin(), words.end(),
            [](const std::string & s1, const std::string & s2) { return s1.size() < s2.size(); });

        // Count the frequency of words
        std::map<std::string, size_t> wordFrequency{};
        for (const std::string& word : words) wordFrequency[word]++;

        // Show the result to the user
        std::cout << "\nNumber of words: " <<  words.size() 
            << "\nLongest word: " << *max << "  (" << max->size() << ")"
            << "\nShortest word: " << *min << "  (" << min->size() << ")"
            << "\nWord frequencies:\n";
        for (const auto& [word, count] : wordFrequency) std::cout << word << " --> " << count << "\n";

    }
    else {
        std::cerr << "*** Error:  Problem with input file\n\n";
    }
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 1970-01-01
    相关资源
    最近更新 更多