练习11.33: 实现你自己版本的单词转换程序。
补充:引用 C++ Primer 5th (中文版)P391 11.3.6
这个程序的功能时这样的:给定一个
string
,将它转换为另一个string
。程序的输入是两个文件。第一个文件保存的是一些规则,用来转换第二个文件中的文本。每条规则由两部分组成:一个可能出现在输入文件中的单词和一个用来替换它的短语。表达的含义是,每当第一个单词出现在输入中时,我们就将它替换为对应的短语。第二个输入文件包含要转换的文本。如果单词转换文件的内容如下所示:
brb be right back k okay? y why r are u you pic picture thk thanks! 18r later
我们希望转换的文本为
where r y y dont u send me a pic k thk 18r
则程序应该生成这样的输出:
where are you why dont you send me a picture okay? thanks! later
环境:
-
系统:Ubuntu 20.04(安装在Windows 11上)
-
编译器:gcc 9.4.0
代码如下:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <map>
using namespace std;
void word_transform(ifstream&, ifstream&); // 管理整个转换过程
map<string, string> buildMap(ifstream&); // 读取转换规则并创建一个map
const string& transform(const string&, const map<string, string>&); // 进行实际转换
int main(int argc, char **argv) {
ifstream ifs_map(argv[1]), ifs_content(argv[2]);
if (ifs_map && ifs_content) {
word_transform(ifs_map, ifs_content);
} else {
cerr << "cant find the documents!" << endl;
return -1;
}
}
void word_transform(ifstream &map_file, ifstream &input) {
auto trans_map = buildMap(map_file); // 保存转换规则
for (string text; getline(input, text);) { // 保存输入中的每一行
istringstream stream(text); // 读取一行输入
bool firstword = true; // 控制是否打印空格
for (string word; stream >> word;) {
if (firstword) {
firstword = false; // 第一个单词签不打印空格
} else {
cout << " ";
}
cout << transform(word, trans_map); // 打印转换结果
}
cout << endl;
}
}
map<string, string> buildMap(ifstream &map_file) {
map<string, string> trans_map; // 保存转换规则
for (string key, value; // key:要替换的单词,value:替换后的内容
map_file >> key && getline(map_file, value);) {
if (value.size() > 1) { // 若value为空,说明没有转换规则,抛出异常
string str = value.substr(1); // 跳过之前的空格
trans_map[key] = str;
} else {
throw runtime_error("no rule for " + key);
}
}
return trans_map;
}
const string& transform(const string &s, const map<string, string> &m) {
auto map_it = m.find(s);
return map_it != m.cend() ? map_it->second : s; // 找到s,替换短语,否则返回原单词
}