【发布时间】:2011-08-02 12:02:16
【问题描述】:
我需要一个函数来将“显式”转义序列转换为相关的不可打印字符。 乙:
char str[] = "\\n";
cout << "Line1" << convert_esc(str) << "Line2" << endl:
会给出这个输出:
Line1
Line2
有没有这样的功能?
【问题讨论】:
我需要一个函数来将“显式”转义序列转换为相关的不可打印字符。 乙:
char str[] = "\\n";
cout << "Line1" << convert_esc(str) << "Line2" << endl:
会给出这个输出:
Line1
Line2
有没有这样的功能?
【问题讨论】:
这是在 Unixy 平台上执行此操作的好方法。
调用操作系统的echo命令进行转换。
string convert_escapes( string input )
{
string buffer(input.size()+1,0);
string cmd = "/usr/bin/env echo -ne \""+input+"\"";
FILE * f = popen(cmd.c_str(),"r"); assert(f);
buffer.resize(fread(&buffer[0],1,buffer.size()-1,f));
fclose(f);
return buffer;
}
【讨论】:
你可以很容易地做到这一点,使用提升字符串算法库。例如:
#include <string>
#include <iostream>
#include <boost/algorithm/string.hpp>
void escape(std::string& str)
{
boost::replace_all(str, "\\\\", "\\");
boost::replace_all(str, "\\t", "\t");
boost::replace_all(str, "\\n", "\n");
// ... add others here ...
}
int main()
{
std::string str = "This\\tis\\n \\\\a test\\n123";
std::cout << str << std::endl << std::endl;
escape(str);
std::cout << str << std::endl;
return 0;
}
这肯定不是最有效的方法(因为它多次迭代字符串),但它紧凑且易于理解。
更新: 正如 ybungalobill 所指出的,这种实现是错误的,只要替换字符串产生一个字符序列,后面的替换正在搜索,或者当替换删除/修改了应该被替换的字符序列时。
第一种情况的示例是"\\\\n" -> "\\n" -> "\n"。当您将"\\\\" -> "\\" 替换放在最后时(乍一看似乎是解决方案),您将获得后一种情况"\\\\n" -> "\\\n" 的示例。显然,这个问题没有简单的解决方案,这使得这种技术只适用于非常简单的转义序列。
如果您需要一个通用(更高效)的解决方案,您应该按照 davka 的建议实现一个迭代字符串的状态机。
【讨论】:
escape("\\\\t") 将返回 "\t" 而不是 "\\t"。
我认为你必须自己编写这样的函数,因为转义字符是编译时特性,即当你编写"\n" 时,编译器会将\n 序列替换为 eol 字符。结果字符串的 长度为 1(不包括终止零字符)。
在您的情况下,字符串 "\\n" 的 长度为 2(同样不包括终止零)并包含 \ 和 n。
您需要扫描您的字符串并在遇到\ 时检查以下字符。如果是合法转义符之一,则应将它们都替换为相应的字符,否则将它们都跳过或保持原样。
string unescape(const string& s)
{
string res;
string::const_iterator it = s.begin();
while (it != s.end())
{
char c = *it++;
if (c == '\\' && it != s.end())
{
switch (*it++) {
case '\\': c = '\\'; break;
case 'n': c = '\n'; break;
case 't': c = '\t'; break;
// all other escapes
default:
// invalid escape sequence - skip it. alternatively you can copy it as is, throw an exception...
continue;
}
}
res += c;
}
return res;
}
【讨论】:
const 输入
我确定有人写过,但它太琐碎了,我怀疑它是否在任何地方专门发布过。
只需使用标准库中的各种“查找”/“替换”式算法自己重新创建即可。
【讨论】:
你考虑过使用 printf 吗? (或其亲属之一)
【讨论】:
printf 来执行此操作?
{'\\', 'n'} 转换为字符串{'\n'}。