所以这样做的目的是读入一个包含数字和名称的文本文件,如下所示:
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
答案 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 *
。制作指针的副本不会制作字符串的副本!下次插入时你插入了相同的指针,所以现在你有两个指向同一个字符串的指针。当该字符串被新输入覆盖时,地图中的所有副本都会更改。