本来以为是一道十分简单的题目,然而…答案依旧有我们需要学习的地方。
通过一个函数将数据从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
#include
#include
#include
#include
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 anna
Smith john henry frieda
Mailer tommy june
Franz
Orlen orley
Ranier 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,哈哈哈,留着以后再看吧(狗头~~)