如何(取消)C/C+中的转义字符串+;? 给出一个计数的字符串(或者是一个字符数组,或者一个包装符,比如 STD::String ),是否有一个“适当”的方式来逃避和/或在C或C++中脱逃,这样“特殊”字符(比如空字符)变成C型转义符,“正常”字符保持原样?
或者我必须手工操作吗?这是一个处理单个字符的函数:如何(取消)C/C+中的转义字符串+;? 给出一个计数的字符串(或者是一个字符数组,或者一个包装符,比如 STD::String ),是否有一个“适当”的方式来逃避和/或在C或C++中脱逃,这样“特殊”字符(比如空字符)变成C型转义符,“正常”字符保持原样?,c++,c,string,escaping,C++,C,String,Escaping,或者我必须手工操作吗?这是一个处理单个字符的函数: /* ** Does not generate hex character constants. ** Always generates triple-digit octal constants. ** Always generates escapes in preference to octal. ** Escape question mark to ensure no trigraphs are generated by repetitiv
/*
** Does not generate hex character constants.
** Always generates triple-digit octal constants.
** Always generates escapes in preference to octal.
** Escape question mark to ensure no trigraphs are generated by repetitive use.
** Handling of 0x80..0xFF is locale-dependent (might be octal, might be literal).
*/
void chr_cstrlit(unsigned char u, char *buffer, size_t buflen)
{
if (buflen < 2)
*buffer = '\0';
else if (isprint(u) && u != '\'' && u != '\"' && u != '\\' && u != '\?')
sprintf(buffer, "%c", u);
else if (buflen < 3)
*buffer = '\0';
else
{
switch (u)
{
case '\a': strcpy(buffer, "\\a"); break;
case '\b': strcpy(buffer, "\\b"); break;
case '\f': strcpy(buffer, "\\f"); break;
case '\n': strcpy(buffer, "\\n"); break;
case '\r': strcpy(buffer, "\\r"); break;
case '\t': strcpy(buffer, "\\t"); break;
case '\v': strcpy(buffer, "\\v"); break;
case '\\': strcpy(buffer, "\\\\"); break;
case '\'': strcpy(buffer, "\\'"); break;
case '\"': strcpy(buffer, "\\\""); break;
case '\?': strcpy(buffer, "\\\?"); break;
default:
if (buflen < 5)
*buffer = '\0';
else
sprintf(buffer, "\\%03o", u);
break;
}
}
}
我喜欢在将字符串写入流时对其进行转义,而不是分配新的缓冲区来包含转义字符串 以下函数使代码可读且简洁
struct Escaped
{
const char* str;
friend inline std::ostream& operator<<(std::ostream& os, const Escaped& e)
{
for (const char* char_p = e.str; *char_p != '\0'; char_p++)
{
switch (*char_p)
{
case '\a': os << "\\a"; break;
case '\b': os << "\\b"; break;
case '\f': os << "\\f"; break;
case '\n': os << "\\n"; break;
case '\r': os << "\\r"; break;
case '\t': os << "\\t"; break;
case '\v': os << "\\v"; break;
case '\\': os << "\\\\"; break;
case '\'': os << "\\'"; break;
case '\"': os << "\\\""; break;
case '\?': os << "\\\?"; break;
default: os << *char_p;
}
}
return os;
}
};
int main()
{
std::cout << Escaped{ "foo\n\tbar" } << std::endl;
}
因此,您正在寻找某种STL函数,它可以将
“\n”
转换为“\\n”
运行时?@muntoo:没错(反之亦然)。它可以是C,但不一定是STL(C++)的一部分。您希望序列:0
65
66
67
显示为文本“\0ABC”
?您希望它将字符转换为C可以理解的内容,还是在特殊字符之前添加反斜杠?您的目标是什么?您是在动态生成C代码吗?我也可以自己实现它,但我希望会有某种标准化的解决方案。但我想没有+无论如何,谢谢你。我相信你可以;我相信我不是唯一一个有这种想法的人。我没有遇到“标准”解决方案。我在2001年9月编写了代码,最后一次更新是在2007年3月。它只是复制粘贴,省略了测试代码和版本控制信息。str_cstrlit
不适用于零长度字符串,缓冲区将没有零终止符。我编辑了代码,但是同行评审失败了,不管是什么原因。只要确保在while循环中写入buffer[0]='\0'
。@lama12345:Hmmmm…是的,你说得对。它还需要一些断言来增强(例如,str!=0&&buffer!=0&&buflen!=0
)。在我编写代码的原始上下文中,零长度字符串永远不可能出现,因此不需要进行额外的检查。但作为一个通用解决方案,它需要一些调整。在上下文中,void
返回也正常-输入不会引起问题。编写通用库代码很难。@Mehrat,您在一篇评论中说过“目标是以已知的、人类可读的形式显示任意字符串”。我的代码实现了这个目标,对吗?我已经看过问题了;对你的反馈要更有建设性。@LightnessRacesInOrbit:这个问题的字面意思是粗体的。@Mehrdad:如果你完全拒绝这个答案和Tim的阅读技巧,是因为这个例子采用了const char*
而不是std::string
,那么这似乎有点小气。您可以简单地更改循环前导。Tim回答的全部要点是,输入是否“计数”并不重要。@LightnessRacesInOrbit:不,这远远不是唯一的问题。如果您阅读了这个问题或我对公认答案的评论,您就会意识到我并没有要求任何人实现,我非常明确地说,如果不是内置的,我可以手工编写一个。然而,这个答案显示了我对我写的几乎所有东西的完全无知,因此我发表了评论。不管你怎么想。@Mehrdad:希望你明天醒来时少发脾气!!
struct Escaped
{
const char* str;
friend inline std::ostream& operator<<(std::ostream& os, const Escaped& e)
{
for (const char* char_p = e.str; *char_p != '\0'; char_p++)
{
switch (*char_p)
{
case '\a': os << "\\a"; break;
case '\b': os << "\\b"; break;
case '\f': os << "\\f"; break;
case '\n': os << "\\n"; break;
case '\r': os << "\\r"; break;
case '\t': os << "\\t"; break;
case '\v': os << "\\v"; break;
case '\\': os << "\\\\"; break;
case '\'': os << "\\'"; break;
case '\"': os << "\\\""; break;
case '\?': os << "\\\?"; break;
default: os << *char_p;
}
}
return os;
}
};
int main()
{
std::cout << Escaped{ "foo\n\tbar" } << std::endl;
}
foo\n bar
//convert '\n' literal to escape code for '\n'
#define STRING "hello\\\\\nworld\\n"
char *p = malloc(strlen(STRING) + 1);
strcpy(p,STRING);
char *s = p;
char c;
for(;*p;++p)
{
while(*p == '\\')
{
++p;
switch(*p){
case '\\':
c = '\\';
goto gstat;
case 'n':
c = '\n';
default:
{
gstat:
strcpy(p-1,p);
*(p-1) = c;
}
break;
}
}
}
printf("%s",s);