将特殊字符(如\ n)转换为其转义版本

时间:2010-12-07 13:52:14

标签: c++ c string

如何在C(++)中将实例"A\r\nB\tC\nD"转换为"A\\r\\nB\\tC\\nD"

理想情况下,仅使用标准库,并为纯C和纯C ++解决方案提供奖励。

5 个答案:

答案 0 :(得分:3)

当然,如果您使用的是宽字符串,请将char替换为wchar_t,将std::string替换为std::wstring

std::string input(/* ... */);
std::string output;
for(std::string::const_iterator it = input.begin(); it != input.end(); ++it)
{
    char currentValue = *it;
    switch (currentValue)
    {
    case L'\t':
        output.append("\\t");
        break;
    case L'\\':
        output.append("\\\\");
        break;
    //.... etc.
    default:
        output.push_back(currentValue);
    }
}

你可以在C中做到这一点但是它会更加困难,因为你事先并不知道缓冲区的大小(虽然你可以做出最坏情况下猜测是原始字符串大小的2倍)。即。

//Disclaimer; it's been a while since I've written pure C, so this may
//have a bug or two.
const char * input = // ...;
size_t inputLen = strlen(input);
char * output = malloc(inputLen * 2);
const char * inputPtr = input;
char * outputPtr = output;
do
{
    char currentValue = *inputPtr;
    switch (currentValue)
    {
    case L'\t':
        *outputPtr++ = '\\';
        *outputPtr = 't';
        break;
    case L'\\':
        *outputPtr++ = '\\';
        *outputPtr = '\\';
        break;
    //.... etc.
    default:
        *outputPtr = currentValue;
    }
} while (++outputPtr, *inputPtr++);

(请记住为C ++版本添加错误处理,例如malloc失败;))

答案 1 :(得分:2)

这是我想出来的......

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

inline char needs_escaping(char val) {
        switch(val) {
                case '\n': return 'n';
                case '\r': return 'r';
                case '\t': return 't';
        }
        return 0;
}

char *escape_string(char *in) {
        unsigned int needed = 0, j = 0, length = strlen(in), i;
        for(i = 0; i < length; i++) {
                if(needs_escaping(in[i])) needed++;
        }

        char *out = malloc(length + needed + 1);
        for(i = 0; i < length; i++) {
                char escape_val = needs_escaping(in[i]);
                if(escape_val) {
                        out[j++] = '\\';
                        out[j++] = escape_val;
                }
                else {
                        out[j++] = in[i];
                }
        }
        out[length + needed] = '\0';    
        return out;
}

int main() {
        char *in  = "A\r\nB\tC\nD";
        char *out = escape_string(in);
        printf("%s\n", out);
        free(out);
        return 0;
}

答案 2 :(得分:1)

我怀疑是否有任何直接执行此操作的标准库函数。最有效的方法是简单地逐个字符地迭代输入缓冲区,有条件地复制到输出缓冲区,使用一些特殊的状态机逻辑来处理'\'等。

我确信有很多方法可以使用strchr()等的各种组合来实现这一点,但在一般情况下可能效率较低。

答案 3 :(得分:0)

我将创建一个包含32个const char*文字的查找表,每个控制代码一个(ASCII 0到ASCII 31)。然后,我将迭代原始字符串,将非控制字符(ASCII&gt; = 32)复制到输出缓冲区,并将查找表中的值替换为ASCII 0--31。

注1:对于C字符串,ASCII 0显然是特殊的(C ++不是这样。)

注2:查找表将包含C转义序列,用于包含它们的代码(\n\r等)和反斜杠加十六进制/八进制/十进制代码。 / p>

答案 4 :(得分:0)

这是C#中的算法。也许您可以将其视为伪代码并将其转换为C ++。

public static string EscapeChars(string Input) {     string Output =“”;

foreach (char c in Input)
{
    switch (c)
    {
        case '\n':
            Output += "\\n";
            break;
        case '\r':
            Output += "\\r";
            break;
        case '\t':
            Output += "\\t";
            break;
        default:
            Output += c;
            break;
    }                
}
return Output;

}