/*
给定一个string, 将它转换成另一个string
程序的输入是2个文件
第一个文件保存的是一些规则,用来转换成第二个文件中的文本
每条规则由两部分组成:一个可能出现在输入文件中的单词和一个用来替换它的短语
表达的含义是,每当第一个单词出现在输入中时,我们就将它替换为对应的短语。
第二个输出文件包含要转换的文本。
*/
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <exception>
#include <stdexcept>
using namespace std;
const string& transforms(const string&, const map<string, string>&);
void word_transform(ifstream&, ifstream& input);
void bulidMap(ifstream&, map<string, string>&);
int main(int argc, char *argv[]) {
if (argc != 3) {
throw runtime_error("wrong number of arguments");
}
ifstream map_file(argv[1]);
if (!map_file) {
throw runtime_error("no transform file!");
}
ifstream input(argv[2]);
if (!input) {
throw runtime_error("no input file!");
}
try {
word_transform(map_file, input);
} catch(runtime_error &error) {//检测建立映射时是否抛出异常
cerr << error.what();
}
return 0;
}
/*
函数形参:接受2个ifstream参数
功能:管理整个转换过程
实现方法描述:先调用buildMap函数建立相应map
再从输入文件中
*/
void word_transform(ifstream& map_file, ifstream& input) {
map<string, string> trans_map;
bulidMap(map_file, trans_map);//将转换规则文件中的要转换的内容映射到替换单词
string Text;//保存输入的每一行
//对输入文件一行一行的读取并进行转换输出
while (getline(input, Text)) {
//string类型输入流 以空格为分界
istringstream stream(Text); //读取每个一个单词
string word; //
bool firstspace = true; //控制是否打空格
while (stream >> word) {
if (firstspace) { //第一个单词前不打印空格, 往后都是先输出一个单词在打印一个空格
firstspace = false;
} else {
cout << " ";
}
//输出转换后的单词,如果没有对应的转换规则则输出原string
cout << transforms(word, trans_map);
}
cout << endl;//将每一个行转换完毕后输出一个空行
}
}
/*
函数形参:ifstream绑定转换规则文件 文件输入流
功能:读取转换规则文件,保存每个单词到替换内容的映射
*/
void bulidMap(ifstream& map_file, map<string, string>& trans_map) {//保存单词与替换单词的映射关系
string key, value;//要替换的单词 及 替换后的内容
while (map_file >> key && getline(map_file, value)) {
if (value.size() > 1) { //检查是否有转换规则,如果有替换内容大小大于1
trans_map[key] = value.substr(1);
} else {
throw runtime_error("no rule for " + key); //无转换规则抛出运行错误异常
}
}
}
/*
函数形参:map 和 string
功能:替换相应的string
*/
const string& transforms(const string& word, const map<string, string>& trans_map) {
//实际的转换操作,程序的核心
auto map_it = trans_map.find(word);
//如果单词在转换规则中
if (map_it != trans_map.cend()) {
return map_it->second;//使用替换短语
} else {
return word;//返回原string
}
}