MultiMap读取数据的麻烦?

时间:2012-04-30 16:20:03

标签: c++

所以这样做的目的是读入一个包含数字和名称的文本文件,如下所示:

50 Leonardo
20 Donatello 
100 Rapheal
40 Michelagelo

我刚刚将它打印出来以检查它是否正确。而不是像我预期的那样获得文本文件的副本,而是为所有名称重复使用姓氏。

这就是我得到的:

Michelagelo 50
Michelagelo 20
Michelagelo 100
Michelagelo 100

代码:

ifstream top;   
    char output[100];
    char* defaultName = "Default";
    int tempTop;
    char* tempName;


    top.open("top.txt");        
    top.clear();
    top.seekg( 0, std::ios_base::beg );


    typedef multimap <char*, int> MM;
    MM top;

    if (top.is_open()) {        
        while (!top.eof()){

            //Get Score
            top>>output;
            tempTop=atoi(output); 


            //Get Name
            top>>output;
            tempName=output;

         cout << "Writing: " << tempName << " and " << tempTop << endl;
         top.insert(MM::value_type(tempName,tempTop));

        }
    }       

    MM::iterator i;

     for(i=top.begin(); i!=top.end(); i++){
          cout << (*i).first << " " <<  (*i).second << endl;
     }
     cout << "Size is: " << top.size() << endl;

我的另一个问题是我正在使用这个多图,因为我认为它会导致排序列表?

非常困惑,并会欣赏我向我展示的新手方式的错误。

TIA

2 个答案:

答案 0 :(得分:2)

您的问题主要源于尝试直接使用char *,而不是像您应该那样使用std::string。如果你坚持使用char*,你需要动态分配你使用的每个字符串,并提供一个比较器对象来比较字符串的内容而不是指针。

底线:除非您别无选择,否则请使用std::string。如果你真的不能使用std::string,你几乎肯定想要编写一个自己的类,它提供至少大致相似的功能(尽管可能没有大量的搜索,替换,等)

当你完成了这个时,你将会遇到另一个小问题:while (!top.eof())几乎可以保证会导致问题(通常看起来会两次读取文件的最后一行)。您几乎肯定希望在尝试读取的结果上读取循环的值和基本延续。

while (top >> number >> name)
    MM.insert(MM::value_type(number, name));

编辑:如果我这样做,我可能会稍微改变它,以避免编写一个显式循环。我会从以下内容开始:

typedef std::pair<std::string, int> v_t;

std::istream &operator>>(std::itream &is, v_t &v) {
     is >> v.second;
     std::getline(is, v.first);
     return is;
}

那应该从输入文件的一行读取数据。然后,您可以使用istream_iterator填充多地图:

std::ifstream top("top.txt");

// define multimap, initialized from stream:    
std::multimap<std::string, int> MM((std::istream_iterator<v_t>(top)),
                                    std::istream_iterator<v_t>());

答案 1 :(得分:1)

插入多图时,您将插入用于模板参数的类型的副本。在这种情况下,它是char *。制作指针的副本不会制作字符串的副本!下次插入时你插入了相同的指针,所以现在你有两个指向同一个字符串的指针。当该字符串被新输入覆盖时,地图中的所有副本都会更改。