【问题标题】:how to read files using containers in STL如何在 STL 中使用容器读取文件
【发布时间】:2018-10-18 03:54:13
【问题描述】:

我必须逐字阅读"testdata.txt" 中的单词,并在另一个文件"dictionary.txt" 中查找相同的单词。我已经实现了在ReadDictionary() 函数中读取"dictionary.txt" 的代码。但是我必须实现ReadTextFile()公共成员函数才能将名为:“testdata.txt”的文件读入私有成员“KnownWords”和“UnknownWords”数据中。 “KnownWords”中只应放入“已知”单词,其余单词应放入“UnknownWords”中。 我必须使用地图和配对,但我不知道如何在我的编程中使用它。有人可以帮我弄清楚这个以获得这个输出吗:

89 known words read.
49 unknown words read.

int main():

WordStats ws;
ws.ReadTxtFile();

头文件:

using namespace std;
typedef map<string, vector<int> > WordMap;     
typedef WordMap::iterator WordMapIter;        

class WordStats
{
public:
    WordStats();
    void ReadDictionary();
    void DisplayDictionary();
    void ReadTxtFile();
private:
    WordMap KnownWords;
    WordMap UnknownWords;
    set<string> Dictionary;
    char Filename[256];
};

这是我的程序:

WordStats::WordStats(){
strcpy(Filename,"testdata.txt");
}

// Reads dictionary.txt into Dictionary
void WordStats::ReadDictionary(){
    string word;    
    ifstream infile("dictionary.txt");
    if(!infile)
    {
        cerr << "Error Opening file 'dictionary.txt. " <<endl;
        exit(1);
    }
    while(getline(infile,word))
    {       
        transform (word.begin(), word.end(), word.begin(), ::tolower);
        Dictionary.insert(word); 
    }
    infile.close();
    cout << endl;
    cout << Dictionary.size() << " words read from dictionary. \n" <<endl;

}
// Reads textfile into KnownWords and UnknownWords
void WordStats::ReadTxtFile(){
    string words;
    vector<string> findword;
    vector<int> count;
    ifstream ifile(Filename);
    if(!ifile)
    {
        cerr << "Error Opening file 'dictionary.txt. " <<endl;
        exit(1);
    }
    while(!ifile.eof())
    {
        getline(ifile,words);
        //KnownWords.insert( pair<string,int>( KnownWords, words ) );
        findword.push_back(words);
        Paragraph = KnownWords.find(words);
        //stuck here
    }
    }

【问题讨论】:

  • 您将哪些 std::vector&lt;int&gt; 值与您的已知和未知单词相关联?
  • 根据要求,我们必须使用vector来push_back我们在字典中找到单词的位置

标签: c++ class dictionary stl keyvaluepair


【解决方案1】:

首先,您使用了错误的数据类型WordMap。在我看来,它应该只是map&lt;string, int&gt;,因为你想计算一个单词在你的文本中出现了多少次。

其次,您应该从文件中读取单词而不是整行文本。您可以使用以下代码:

std::string word;
while (ifile >> word) {
    if (Dictionary.find(word) != Dictionary.end()) {
        // WordMap::value_type ... creates instance of std::pair object
        auto it = KnownWords.insert(KnownWords.end(), WordMap::value_type(word, 0));
        it->second++;
    } else {
        auto it = UnknownWords.insert(UnknownWords.end(), WordMap::value_type(word, 0));
        it->second++;
    }
}

【讨论】:

  • 你用“它”做什么?
  • 它给了我警告“'它'没有命名类型”我试图把'Paragraph'作为一个迭代器它给了我同样的错误信息。
  • it 是一个迭代器。如果您的编译器不支持关键字 auto,您应该升级它或启用 C++11 支持。
  • 我试过了,现在编译器给了我这个错误:没有匹配函数调用 'std::pair, std::vector >::对(std::string&, int)'
【解决方案2】:

您似乎需要检查 Dictionary 以查看它是否包含您阅读的每个单词,然后选择要修改 KnownWordsUnknownWords 中的哪一个。

void WordStats::ReadTxtFile(){
    std::ifstream ifile(Filename);
    if(!ifile)
    {
        std::cerr << "Error Opening file " << Filename << std::endl;
        exit(1);
    }

我已经清理了你的本地声明,所以变量的存活时间尽可能短。

假设文件包含由空格和换行符分隔的单词,读取每个单词

    for (std::string word; ifile >> word; )
    {

小写

        transform (word.begin(), word.end(), word.begin(), ::tolower);

然后看看是不是在Dictionary

        if (Dictionary.count(word))
        {

记录KnownWords[word]中的位置。

            KnownWords[word].push_back(ifile.tellg());
        }
        else
        {

UnknownWords[word]

            UnknownWords[word].push_back(ifile.tellg()); 
        }
    }

然后显示其中的sizes 以获得所需的输出。

    std::cout << KnownWords.size() << " known words read." << std::endl;
    std::cout << UnknownWords.size() << " unknown words read." << std::endl;
}

您可以使用条件表达式替换复制操作的条件语句。注意Words声明中的引用类型

WordMap & Words = (Dictionary.count(word) ? KnownWords : UnknownWords);
Words[word].push_back(ifile.tellg()); 

作为一个完整的函数:

void WordStats::ReadTxtFile(){
    std::ifstream ifile(Filename);
    if(!ifile)
    {
        std::cerr << "Error Opening file " << Filename << std::endl;
        exit(1);
    }

    for (std::string word; ifile >> word; )
    {
        transform (word.begin(), word.end(), word.begin(), ::tolower);
        WordMap & Words = (Dictionary.count(word) ? KnownWords : UnknownWords);
        Words[word].push_back(ifile.tellg()); 
    }

    std::cout << KnownWords.size() << " known words read." << std::endl;
    std::cout << UnknownWords.size() << " unknown words read." << std::endl;
}

【讨论】:

  • 顺便说一句,我对void MyClass::doAction() 之类的函数特别讨厌,因为它们不使用类型系统来告诉您正在发生的事情。询问您的讲师为什么选择这些作为 WordStats 的成员,而不是 WordStats ReadFromStream(std::istream &amp; source, std::set&lt;std::string&gt; Dictionary) 之类的成员
  • 我尝试了代码,但它没有给我确切的输出。我应该在 cout , std::vector >::count()'`.
  • 如果我像 KnownWords.count(word) 或 UnknownWords.count(word) 这样在其中输入“word”,则两者的输出都为零。
  • 哎呀,我的意思是“大小”
  • 以及如何打印出 KnownWord 和 UnkownWord 的位置?
猜你喜欢
  • 2014-12-01
  • 1970-01-01
  • 2018-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
相关资源
最近更新 更多