定义一个map,家庭姓氏为Key,家庭所有的孩子的姓名为value,允许用户通过姓氏查询。以及一个出现的问题。

本来以为是一道十分简单的题目,然而…答案依旧有我们需要学习的地方。

通过一个函数将数据从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

但是这里出现了问题:
定义一个map,家庭姓氏为Key,家庭所有的孩子的姓名为value,允许用户通过姓氏查询。以及一个出现的问题。_第1张图片
只有姓氏的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,哈哈哈,留着以后再看吧(狗头~~)

你可能感兴趣的:(定义一个map,家庭姓氏为Key,家庭所有的孩子的姓名为value,允许用户通过姓氏查询。以及一个出现的问题。)