本来以为是一道十分简单的题目,然而…答案依旧有我们需要学习的地方。
通过一个函数将数据从namefile文件中存储进map
void populate_map(ifstream& in_file, map<string, vector<string> > &families){string textline;while (getline(in_file, textline)){string fam_name;vector<string> child;string::size_type pos = 0, prev_pos = 0, text_size = textline.size();while ((pos = textline.find_first_of(\' \', pos)) != string::npos) //对每个用\' \'分隔的字符串进行操作{string::size_type end_pos = pos - prev_pos;if (!prev_pos) //当prev_pos为0时,为家庭的姓{fam_name = textline.substr(prev_pos, end_pos);}else{child.push_back(textline.substr(prev_pos, end_pos));}prev_pos = ++pos;}if (prev_pos < text_size) //处理最后一个孩子的名字{child.push_back(textline.substr(prev_pos, pos - prev_pos));}if (!families.count(fam_name)) //如果家庭不存在{families[fam_name] = child;}else //家庭存在{cerr << \"sorry, the family \" << fam_name << \" is already exist!\" << endl;}}}
实现:
#include <iostream>#include <map>#include <string>#include <vector>#include <fstream>using namespace std;void populate_map(ifstream& in_file, map<string, vector<string> > &families);void display(const map<string, vector<string> > &families, ostream& os);void has_child(map<string, vector<string> >::const_iterator& it, ostream& os= cout);void query(const string& family, const map<string, vector<string> >& families);int main(){map<string, vector<string> > families;ifstream in_file(\"namefile.txt\"); //打开输入文件if (!in_file){cerr << \"the file cannot open!!\";return -1;}populate_map(in_file, families); //从namefile中填写map//用户进行查询string family_name;while (1){cout << \"please enter a family name to query (q to quit): \";getline(cin, family_name);if (family_name == \"q\"){break;}query(family_name, families);}//报告所有家庭的信息display(families, cout);system(\"pause\");return 0;}void populate_map(ifstream& in_file, map<string, vector<string> > &families){string textline;while (getline(in_file, textline)){string fam_name;vector<string> child;string::size_type pos = 0, prev_pos = 0, text_size = textline.size();while ((pos = textline.find_first_of(\' \', pos)) != string::npos) //对每个用\' \'分隔的字符串进行操作{string::size_type end_pos = pos - prev_pos;if (!prev_pos) //当prev_pos为0时,为家庭的姓{fam_name = textline.substr(prev_pos, end_pos);}else{child.push_back(textline.substr(prev_pos, end_pos));}prev_pos = ++pos;}if (prev_pos < text_size) //处理最后一个孩子的名字{child.push_back(textline.substr(prev_pos, pos - prev_pos));}if (!families.count(fam_name)) //如果家庭不存在{families[fam_name] = child;}else //家庭存在{cerr << \"sorry, the family \" << fam_name << \" is already exist!\" << endl;}}}void has_child(map<string, vector<string> >::const_iterator &it, ostream& os) //当有孩子时,所需要报告的消息,为了简化代码{os << \" has \" << it -> second.size() << \" children: \";vector<string>::const_iterator vit = it -> second.begin();vector<string>::const_iterator end_vit = it -> second.end();while (vit != end_vit){os << *vit << \" \";vit++;}os << endl;}void display(const map<string, vector<string> > &families, ostream& os) //将map中的信息报告{map<string, vector<string> >::const_iterator it = families.begin();map<string, vector<string> >::const_iterator end_it = families.end();while (it != end_it){os << \"the family \" << it -> first;if (it->second.empty()){os << \" has no child\" << endl;}else{has_child(it);}it++;}}void query(const string& family, const map<string, vector<string> >& families) //报告用户查询家庭的信息{map<string, vector<string> >::const_iterator it = families.find(family);if (it == families.end()){cout << \"sorry, the family was not recorded yet!\" << endl;return;}cout << \"the family \" << it->first;if (it->second.empty()){cout << \" has no child\" << endl;}else{has_child(it);}}
namefile:
Lippman dabby annaSmith john henry friedaMailer tommy juneFranzOrlen orleyRanier alpjonse lou robert brodie
但是这里出现了问题:
只有姓氏的Franz被认为是孩子的姓名,而姓氏则被认为是“ ”。
通过debugging,发现应该是下面while一段代码块并没有执行,导致下一段处理最后一个孩子名字的代码段将Franz设置成为孩子的名字。
while ((pos = textline.find_first_of(\' \', pos)) != string::npos) //对每个用\' \'分隔的字符串进行操作{string::size_type end_pos = pos - prev_pos;if (!prev_pos) //当prev_pos为0时,为家庭的姓{fam_name = textline.substr(prev_pos, end_pos);}else{child.push_back(textline.substr(prev_pos, end_pos));}prev_pos = ++pos;}
然而。。。我并不会改这个bug,哈哈哈,留着以后再看吧(狗头~~)