如何在C(++)中将实例"A\r\nB\tC\nD"
转换为"A\\r\\nB\\tC\\nD"
?
理想情况下,仅使用标准库,并为纯C和纯C ++解决方案提供奖励。
答案 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;
}