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

C++ C++;在main中调用打印地图的函数时出现问题,c++,function,map,main,C++,Function,Map,Main,我试图打印地图的内容,这就是我的代码失败的地方。我已经测试了我所有的方法,从文件中读取、归档单词、将其放入地图中都没有问题,甚至打印功能也在工作。 但是,当我从main调用printer函数时,它不会打印地图。 我不熟悉多态性,我认为我的错误在于如何将映射传递给main中的函数 这是我的主要课程: using namespace std; #include <iostream> #include "ReadWords.h" #include "ReadPunctWords.h" #i

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

这是我的主要课程:

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;

}
使用名称空间std;
#包括
#包括“ReadWords.h”
#包括“readputchwords.h”
#包括“ReadNumWords.h”
#包括“ReadCapWords.h”
#包括“MapWorks.h”
#包括
#包括
#包括
#包括
/**
*此主函数使用所有其他类。
*/
int main(){
char*name=“RomeoJuliet.txt”;
//ReadPunctWords&obj=*新的ReadPunctWords(名称);
阅读文字obj(姓名);
字符串startSearch=“BEGIN”;
字符串endSearch=“FINIS”;
读写单词rpw;
ReadCapWords rcw;
ReadNumWords rnw;
MapWorks mw;
while(rpw.isNextWord()){
字符串tempword=obj.getNextWord();
if(tempword==startSearch){
打破
}
}
while(rpw.isNextWord()){
字符串tempword=obj.getNextWord();
if(tempword==endSearch){
打破
}
否则{
if(rpw.过滤器(临时字)){
mw.addToMap(tempword,mw.mappinct);
}
if(rcw.过滤器(临时字)){
mw.addToMap(tempword,mw.mapCap);
}
if(rnw.过滤器(临时字)){
mw.addToMap(tempword,mw.mapNum);
}
}
}
mw.printMap(mw.mappint);
mw.printMap(mw.mapCap);
mw.printMap(mw.mapNum);
//清晰地图
mw.clearMap(mw.mapPunct);
mw.clearMap(mw.mapCap);
mw.clearMap(mw.mapNum);
//关闭文件
//obj.close();
//删除&obj;
//退出(0);//正常退出
返回0;
}
以及my MapWorks.cpp,其中包含地图和与地图相关的功能:

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();

}
使用名称空间std;
#包括
#包括
#包括
#包括
#包括“MapWorks.h”
/**
*MapWorks类构建地图并进行地图处理和打印
*/
MapWorks::MapWorks(){}
void MapWorks::addToMap(字符串myword、map和myMap){
int n=myMap[myword];
myMap[myword]=n+1;
}
void MapWorks::printMap(map和myMap){
对于(map::iterator it=myMap.begin();it!=myMap.end();++it)
{

是否可以先忘记递增迭代器:

while(it!=myMap.end()){
    cout<<(*it).first<<" ==> "<<(*it).second<<endl;
    // you forgot this:
    it++;
}
while(it!=myMap.end()){

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

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

void MapWorks::addToMap(string myword, map<string, int>& myMap)
{
    // definition...
}
当您在创建对象的同一函数末尾删除该对象时,您可以执行此操作(与使用
MapWorks mw;
时完全相同)


如果您必须使用动态分配的对象,只使用指针而不是引用更为常见,但强烈建议使用某种智能指针,这样您就不必记得显式调用
delete

如果可能,我建议将逻辑拆分为稍微更小的单元,然后按现在,
main
比我想看到的要多得多,而且(特别是)比我想看到的更了解类的内部结构

如果我这样做的话,我会从一个知道如何过滤单词的地图开始,这样它只能接受它应该接受的:

class Map { 
    std::map<std::string, int> counts;
public:
    struct Filter { 
        virtual bool operator()(std::string const &) const = 0;
    };

    Map(Filter const &f) : filter(f) {}

    bool InsertWord(std::string const &word) { 
        return filter(word) && (++counts[word] != 0);
    }

    friend std::ostream &operator<<(std::ostream &os, Map const &m) { 
        std::copy(m.counts.begin(), 
                  m.counts.end(), 
                  std::ostream_iterator<count>(std::cout, "\n"));
        return os;
    }
private:
    Filter const &filter;
};
然后,MapWorks可以将几乎所有实际工作委托给地图(地图反过来使用过滤器):


还有一些其他的细节,比如定义计数类型和为计数类型定义插入器,但这些都是很小的细节。

(我希望我们有一个更好的方法来格式化注释!)谢谢,我将尝试修复此问题并查看其效果。您好,您能再看一次吗?我更新了问题并实施了这些更改。谢谢您没有更改
addToMap
函数以引用传递的映射。这是否反映了您的代码?您还删除了
delete&obj
但没有更改
obj
作为堆栈对象,例如,
readpointwords obj(名称)
老实说,我完全迷路了:-)谢谢你的帮助。好吧,修改后我会遇到各种各样的错误。如果我的addToMap函数通过引用来获取传递的映射,那么我想我需要更改头文件中的函数来获取映射的引用?我不确定这是什么语法。我将使obj成为一个堆栈对象并在一分钟内更新它。我感谢您的帮助,但我是一名编程初学者:-)希望这不会花费太多时间来帮助我。我认为您的意思是:
ReadPunctWords obj(名称);
ReadPunctWords*obj=新的PunctWords(名称)
。从RAII的描述来看,我认为是前者。我已经这样做了,谢谢!但是它仍然不起作用……你能发现其他的东西吗?谢谢,我在尝试注释掉的函数时已经这样做了,但它仍然不起作用。你能看到其他的错误吗?注释掉的函数增加了一个不同于o的迭代器它用于打印的ne,因此它也是错误的。如果不查看其他源代码(如MapWorks.h和ReadWords..MapWorks.h:#ifndef MapWorks_h#define MapWorks_h#include#include使用名称空间std;/***MapWorks类构建地图并进行地图处理和打印*/类,就很难知道还有什么问题MapWorks{public:map mapPunct;//(单词,出现次数)map mapNum;//(单词,出现次数)map mapCap;//(单词,出现次数)MapWorks();void addToMap(字符串,映射);//向映射添加单词void printMap(映射);//打印映射void clearMap(映射);//清除映射
// ReadPunctWords &obj = *new ReadPunctWords(name);
// should likely be:
ReadPunctWords obj(name);
// same applies to other 'newed' 'references'
// and then there's no need to do
// delete &obj;

// exit(0); // normal exit
// should probably be just a
return 0;

// obj.close();
// can be called in the destructor of ReadPunctWords class
// and RAII will help you get your file closed correctly when needed

// void MapWorks::printMap (map<string, int>myMap)
// should better be:
void MapWorks::printMap (const std::map<string, int> &myMap)
// same applies to other functions in your code

// here's how your commented-out function could look like
void MapWorks::printMap(const std::map<string, int> &myMap) {
    typedef std::map<string, int>::iterator mapsi;
    for (mapsi m = myMap.begin(); m != myMap.end(); ++m) {
        std::cout << (*m).first << " ==> " << (*m).second << "\n";
    }
}

// void MapWorks::addToMap(string myword, map<string, int>myMap)
// should be:
void MapWorks::addToMap(std::string myword, std::map<string, int> &myMap)
map<string, int>::iterator it = myMap.begin();
cout<<"test"<<endl;
while(it!=myMap.end()){
cout<<(*it).first<<" ==> "<<(*it).second<<endl;
}
for (std::map<string, int>::iterator it = myMap.begin(); it != myMap.end(); ++it)
{
    std::cout << it->first << " ==> " << it->second << '\n';
}
void addToMap(string myword, map<string, int>& myMap);
void MapWorks::addToMap(string myword, map<string, int>& myMap)
{
    // definition...
}
ReadWords &rnw = *new ReadNumWords();
ReadNumWords rnw;
class Map { 
    std::map<std::string, int> counts;
public:
    struct Filter { 
        virtual bool operator()(std::string const &) const = 0;
    };

    Map(Filter const &f) : filter(f) {}

    bool InsertWord(std::string const &word) { 
        return filter(word) && (++counts[word] != 0);
    }

    friend std::ostream &operator<<(std::ostream &os, Map const &m) { 
        std::copy(m.counts.begin(), 
                  m.counts.end(), 
                  std::ostream_iterator<count>(std::cout, "\n"));
        return os;
    }
private:
    Filter const &filter;
};
struct Num : Map::Filter { 
    bool operator()(std::string const &w) const {
        return isdigit(w[0]) != 0;
    }
};

struct Punct : Map::Filter { 
    bool operator()(std::string const &w) const { 
        return ispunct(w[0]) != 0;
    }
};

struct Letter : Map::Filter { 
    bool operator()(std::string const &w) const { 
        return isalpha(w[0]) != 0;
    }
};
class MapWorks { 
    Map num;
    Map punct;
    Map letter;
public:

    // For the moment, these allocations just leak.
    // As long as we only create one MapWorks object,
    // they're probably not worth fixing.
    MapWorks() 
        : num(Map(*new Num())), 
          punct(Map(*new Punct())), 
          letter(Map(*new Letter())) 
    {}

    // Try adding the word until we find a Map 
    // that accepts it.
    bool push_back(std::string const &word) {
        return num.InsertWord(word) 
            || punct.InsertWord(word) 
            || letter.InsertWord(word);
    }

    // Write out by writing out the individual Map's:
    friend std::ostream &operator<<(std::ostream &os, MapWorks const &m) {
        return os << m.num << "\n" << m.punct << "\n" << m.letter << "\n";
    }       
};
int main() { 
    MapWorks m;

    std::string temp;
    while (std::cin >> temp)
        m.push_back(temp);

    std::cout << m;
    return 0;

}