C++ 在 main 中调用打印 map 的函数时出现问题

标签 c++ function dictionary program-entry-point

我正在尝试打印 map 的内容,这就是我的代码失败的地方。我已经测试了所有方法,从文件读取、过滤单词、将其放入 map 中都没有问题,甚至打印功能也正常工作。 但是,当我从 main 调用打印机函数时,它不会打印 map 。 我是多态性的新手,我认为我的错误在于如何将映射传递给 main 中的函数。

这是我的主要类(class):

using namespace std;
#include <iostream>
#include "ReadWords.h"
#include "ReadPunctWords.h"
#include "ReadNumWords.h"
#include "ReadCapWords.h"
#include "MapWorks.h"
#include <fstream>
#include <string>
#include <map>
#include <iterator>

/**
 * This main function uses all other classes.
 */
int main() {


   char* name = "RomeoJuliet.txt";
   //ReadPunctWords &obj = *new ReadPunctWords(name);
   ReadPunctWords obj(name);
   string startSearch="BEGIN";
   string endSearch="FINIS";


   ReadPunctWords rpw;
   ReadCapWords rcw;
   ReadNumWords rnw;
   MapWorks mw;

   while(rpw.isNextWord()){
       string tempword = obj.getNextWord();
       if(tempword == startSearch){
           break;
       }
   }
   while(rpw.isNextWord()){
       string tempword = obj.getNextWord();
       if(tempword == endSearch){
           break;
       }
       else{
               if(rpw.filter(tempword)){
                   mw.addToMap(tempword, mw.mapPunct);
               }

               if(rcw.filter(tempword)){
                   mw.addToMap(tempword, mw.mapCap);
               }

               if(rnw.filter(tempword)){
                   mw.addToMap(tempword, mw.mapNum);
               }
           }
   }


   mw.printMap(mw.mapPunct);
   mw.printMap(mw.mapCap);
   mw.printMap(mw.mapNum);


   //clear map
   mw.clearMap(mw.mapPunct);
   mw.clearMap(mw.mapCap);
   mw.clearMap(mw.mapNum);

   //close the file
   //obj.close();


   //delete &obj;

   //exit(0); // normal exit
   return 0;

}

还有我的MapWorks.cpp,其中包含 map 以及与 map 相关的函数:

using namespace std;
#include <iostream>
#include <string>
#include <map>
#include <iterator>
#include "MapWorks.h"

/**
 * MapWorks class builds the maps and does the map processing and printing
 */


MapWorks::MapWorks() {}

void MapWorks::addToMap(string myword, map<string, int> & myMap){
    int n = myMap[myword];
    myMap[myword]= n+1;
}


void MapWorks::printMap (map<string, int> &myMap){

    for (map<string, int>::iterator it = myMap.begin(); it != myMap.end(); ++it)
    {
        cout << it->first << " ==> " << it->second << '\n'<<endl;
    }
}


//delete entries in map
void MapWorks::clearMap(map<string, int>myMap) {
    myMap.clear();

}

MapWorks.h:

#ifndef MAPWORKS_H
#define MAPWORKS_H
#include <string>
#include <map>
using namespace std;


/**
 * MapWorks class builds the maps and does the map processing and printing
 */

class MapWorks {
    public:

    map<string, int> mapPunct; //(word, number of occurences)
    map<string, int> mapNum; //(word, number of occurences)
    map<string, int> mapCap; //(word, number of occurences)

    MapWorks();

    void addToMap(string myword, map<string, int> & myMap); //adds words to a map

    void printMap (map<string, int> &myMap); //prints the map

    void clearMap(map<string, int>); //clear map
};

#endif

我的ReadWords.h:

/**
 * ReadWords class, the base class for ReadNumWords, ReadPunctWords, ReadCapWords
 */

#ifndef READWORDS_H
#define READWORDS_H

using namespace std;
#include <string>
#include <fstream>
#include<iostream>

 class ReadWords
 {
   private:
     string nextword;
     ifstream wordfile;
     bool eoffound;

   public:
    /**
     * Constructor. Opens the file with the default name "text.txt".
     * Program exits with an error message if the file does not exist.
     */
     ReadWords();

    /**
     * Constructor. Opens the file with the given filename.
     * Program exits with an error message if the file does not exist.
     * @param filename - a C string naming the file to read.
     */
     ReadWords(char *filename);

    /**
     * Closes the file.
     */
     void close();

    /**
     * Returns a string, being the next word in the file.
     * @return - string - next word.
     */
     string getNextWord();

    /**
     * Returns true if there is a further word in the file, false if we have reached the
     * end of file.
     * @return - bool - !eof
     */
     bool isNextWord();

     //pure virtual function for filter
     virtual bool filter(string word)=0;

    /**
     * Fix the word by the definition of "word"
     * end of file.
     * @return - string
     */
     string fix(string word);
 };

 #endif

还有我的 ReadPunctWords(ReadNumWords 和 ReadCapWords 完全相同,只是检查单词是否包含数字或大写字母,而不是像这里这样的标点符号):

#ifndef READPUNCTWORDS_H
#define READPUNCTWORDS_H
using namespace std;
#include <string>
#include "ReadWords.h"

/**
 * ReadPunctWords inherits ReadWords, so MUST define the function filter.
 * It chooses to override the default constructor.
 */
class ReadPunctWords: public ReadWords {
    public:
    ReadPunctWords();
    ReadPunctWords(char *filename): ReadWords(filename){};
    virtual bool filter(string word);
};

#endif

如果您能提供任何帮助,我将不胜感激。 谢谢,阿德里安娜

最佳答案

您的代码中存在许多潜在问题,但最明显的可能是导致 printMap这个 while 循环没有按预期工作。

map<string, int>::iterator it = myMap.begin();
cout<<"test"<<endl;
while(it!=myMap.end()){
cout<<(*it).first<<" ==> "<<(*it).second<<endl;
}

您不会在任何地方增加迭代器,因此要么不会打印任何内容(如果映射为空),要么第一个项目将一遍又一遍地打印并且循环不会终止。

编写此循环的惯用方法是使用 for 循环。

for (std::map<string, int>::iterator it = myMap.begin(); it != myMap.end(); ++it)
{
    std::cout << it->first << " ==> " << it->second << '\n';
}

另一个问题是您的 addToMap函数可能无法按预期工作,因为您按值将映射传递给函数,这意味着该函数向其中添加项目的映射实际上是传入的映射的拷贝.

当控制权传递给调用函数时,该拷贝将被销毁,并且传递的映射仍然为空。

要通过引用传递 map ,您需要添加 &函数声明中参数的类型。

即在头文件中,MapWorks类定义:

void addToMap(string myword, map<string, int>& myMap);

在源文件中:

void MapWorks::addToMap(string myword, map<string, int>& myMap)
{
    // definition...
}

至少可以说,您对动态分配对象的引用的使用是不寻常的。出于您的目的,我认为没有任何必要这样做:

ReadWords &rnw = *new ReadNumWords();

当您在创建该对象的同一函数末尾删除该对象时。您可以这样做(就像 MapWorks mw; 一样)。

ReadNumWords rnw;

如果您必须使用动态分配的对象,则仅使用指针而不是引用更为常见,但强烈建议使用某种智能指针,这样您就不必记住调用 delete明确地。

关于C++ 在 main 中调用打印 map 的函数时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2075008/

相关文章:

c++ - 如何从函数/类接收 map<A, B>&?

c++ - 为什么 std::sqrt() 在 C++ 中对 double 据不能正常工作?

VBA map 实现

Python:根据字典中的内容从列表中获取字典

javascript - 以另一个函数作为参数调用的函数,不能完全理解它的概念

c - 如何以正确的方式将结构的数组传递给我的函数?

javascript - 红灯警告

c++ - TBB concurrent_queue,unsafe_size有多不安全?

c++ - 为什么这段代码不能用 VS2010 和 gcc 4.8.1 编译

c++ - 未解析为候选容器的模板运算符模板