Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何(取消)C/C+中的转义字符串+;? 给出一个计数的字符串(或者是一个字符数组,或者一个包装符,比如 STD::String ),是否有一个“适当”的方式来逃避和/或在C或C++中脱逃,这样“特殊”字符(比如空字符)变成C型转义符,“正常”字符保持原样?_C++_C_String_Escaping - Fatal编程技术网

如何(取消)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);