C++学习笔记:单词转换程序

C++primer 5th第11章(关联容器)的末尾给出了一个单词转换程序,我觉得非常有意思。里面运用了很多关联容器和IO处理的基本操作,虽然书上已经给出了这个程序的源代码,但我还是准备在这里贴出来分析一下,讲一些我自己的理解。


单词转换程序

功能:从一个文本文件中读取转换规则,比如:

u you
hs handsome
y yes
i I
k know

将另一个文本中所有可以被替换的单词替换,比如:

原文本
u are so hs
y i k i am hs

转换后的文本
you are so handsome
yes I know I am handsome

很有意思,不是吗?现在我们来考虑怎么去实现这个程序。

  • 我们需要一个函数建立一个转换映射–即建立一个map,键key是待转换文本,值value是转换后的文本
  • 需要一个函数靠上面创建的map进行实际转换工作
  • 最后还要一个函数处理文件的读取以及调用上面两个函数

以下程序可以在C++primer第五版第391-393页找到,但是这里的注释是我自己写的


map<string, string> buildMap(ifstream &map_file) {
//建立转换映射,将转换规则存入一个map并返回该map
   map<string, string> trans_map;					            //定义一个保存转换规则的map
   string key;													//map的key,待转换的单词
   string value;												//map的value,转换的结果
 while(map_file>>key&&getline(map_file,value))                  /*每次循环key获得“转换规则”文本中一行的首单词,
                                                                 即待转换的单词,value获得该行剩下的内容,即“空格+目标单词”*/																						
   	if (value.size() > 1)                                       //防止只有一个单词
   		trans_map[key] = value.substr(1);      					//去除空格,建立映射
   	else
   		throw runtime_error("no rule for " + key);  			//抛出异常信息
   return trans_map;
}
const string &transform(const string &s, const map<string, string> &m) {
//转换工作,输入需要转换的string和存有转换规则的map,返回转换后的string
	auto map_it = m.find(s);						//查找是否存在需要转换的单词
	if (map_it != m.cend())							//如果找到了,进行转换
		return map_it->second;
	else
		return s;									//否则原样反回
}
void word_transform(ifstream &map_file, ifstream &input) {
//这个函数是与外部文本的接口
	auto trans_map = buildMap(map_file);			//调用函数,建立映射
	string text;
	while (getline(input, text)) {					//将待转换文本的一行存入text
		istringstream stream(text);					//text与一个string输入流绑定
		string word;
		bool firstword = true;						//控制是否打印空格
		while (stream >> word) {					//word将通过循环,保存text中的每个单词
			if (firstword)						   //开头不需要空格,其他位置单词之间需要空格
				firstword = false;
			else
				cout << " ";
			cout << transform(word, trans_map);			//调用transform函数对读取的单词进行转换
		}
		cout << endl;
	}
}

思考

经过测试,转换完成了目的。而且即使读入的是中文字符,转换也能完成,但是中文字之间显然是没有空格的,所以程序需要进行修改。还有一个问题是,即使要转换的是纯英文字符,遇到了标点符号等也会出现无法转换的情况,解决这个问题要么把单词连着标点输进转换规则,要么就修改程序。

一些重要的知识点

  • getline(istream,line) 读入一整行,即遇到回车结束,属于string头文件
  • istream >> strword 读入一个单词,即遇到空格结束
  • map的查找函数find查找键值,返回一个迭代器,若没有找到,则返回尾后迭代器

参考资料

  • C++ primer 5th
发布了19 篇原创文章 · 获赞 17 · 访问量 2949
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览