您基本上是在编写一个简单的词法分析器;手动执行此操作的常用方法是使用状态机。
#include <iostream>
#include <stdexcept>
#include <sstream>
using namespace std;
int main() {
char c;
istringstream s("foo \\n bar");
enum { CHARACTER, ESCAPE } state = CHARACTER;
while (s.get(c)) {
switch (state) {
case CHARACTER:
if (c == '\\') {
state = ESCAPE;
} else {
cout << c;
}
break;
case ESCAPE:
switch (c) {
case 'n': cout << '\n'; break;
case 't': cout << '\t'; break;
default:
throw runtime_error("unknown escape");
}
state = CHARACTER;
break;
}
}
}
当然,对于这个简单的例子,转义表可以是 a map<char, char>
,但如果你想支持更多奇特的转义,例如十六进制数字\xNN
在哪里NN
,那么概括一下是值得的。
状态机方法的优点是有一个读取字符的位置。各个状态只负责将该字符添加到他们认为合适的输出中,并通过分配state
变量来转换到其他状态。