C++ 具有特殊字符的字符串的控制台输出
是否有一种或多或少的标准方法来输出包含特殊字符(如ASCII控制代码)的字符串,以使输出为有效的C/C++文本字符串,并带有转义序列 预期输出的示例:C++ 具有特殊字符的字符串的控制台输出,c++,c,formatted,C++,C,Formatted,是否有一种或多或少的标准方法来输出包含特殊字符(如ASCII控制代码)的字符串,以使输出为有效的C/C++文本字符串,并带有转义序列 预期输出的示例:This\nis\na\\test\n\n她说,“你好吗?”\n 如果不小心,输出将是 This is a\test She said, "How are you?" 不是你想要的。根据你可能试图实现的目标,我可以建议以下解决方案:只需将任何不可打印的字符替换为“\xnn”(nn是字符的ascii码。这可以归结为 void myprint (c
This\nis\na\\test\n\n她说,“你好吗?”\n
如果不小心,输出将是
This
is
a\test
She said, "How are you?"
不是你想要的。根据你可能试图实现的目标,我可以建议以下解决方案:只需将任何不可打印的字符替换为“\xnn”(nn是字符的ascii码。这可以归结为
void myprint (char *s) {
while (*s) {
printf(isalnum((unsigned char) *s) ? "%c" : "\\%03hho", *s);
s++;
}
}
这当然不会使用像
\n
(但是\x0a
)这样的特殊缩写,但这应该不会是一个问题。如果这对某人有帮助,我会很快将其组合起来:
void printfe(char* string)
{
for (char c= *string; c; c= *(++string))
{
switch (c)
{
case '\a': printf("\\a"); break;
case '\b': printf("\\b"); break;
case '\f': printf("\\f"); break;
case '\n': printf("\\n"); break;
case '\r': printf("\\r"); break;
case '\t': printf("\\t"); break;
case '\v': printf("\\v"); break;
case '\\': printf("\\\\"); break;
case '\'': printf("\\\'"); break;
case '\"': printf("\\\""); break;
case '\?': printf("\\?"); break;
default: (c < ' ' || c > '~') ? printf("\\%03o", c) : putchar(c); break;
}
}
}
void printfe(字符*字符串)
{
for(字符c=*字符串;c;c=*(++字符串))
{
开关(c)
{
大小写“\a”:printf(“\\a”);中断;
大小写“\b”:printf(“\\b”);中断;
大小写“\f”:printf(“\\f”);中断;
大小写“\n”:printf(“\\n”);中断;
大小写“\r”:printf(“\\r”);中断;
大小写“\t”:printf(“\\t”);中断;
大小写“\v”:printf(“\\v”);中断;
大小写“\\”:printf(“\\\”);break;
大小写“\”:printf(“\\\”);break;
大小写“\”:printf(“\ \”);break;
大小写“\?”:printf(“\?”);break;
默认值:(c)<'''\'c>'~'?printf(\\%03o',c):putchar(c);break;
}
}
}
(请注意
c的潜在不可移植性
,我想避免任何库引用)。打印转义字符串显然很棘手
问题包括
char
void EscapePrint(char ch) {
// 1st handle all simple-escape-sequence C11 6.4.4.4
// The important one to detect is the escape character `\`
// Delete or adjust these 2 arrays per code's goals
static const char *escapev = "\a\b\t\n\v\f\r\"\'\?\\";
static const char *escapec = "abtnvfr\"\'\?\\";
char *p = strchr(escapev, (unsigned char) ch);
if (p && *p) {
printf("\\%c", escapec[p - escapev]);
}
// if printable, just print it.
else if (isprint((unsigned char) ch)) {
fputc(ch, stdout);
}
// else use octal escape
else {
// Use octal as hex is problematic reading back
printf("\\%03hho", ch);
}
}
char
范围超过9位的罕见机器上是一个问题。这可以在字符串级别使用十六进制转义序列来处理,而不是在char
基础上使用char
来处理,因为十六进制转义序列需要限制。例如:
input 2 `char`: \1 A
// v----- intervening space
output text including ": "\\x1" "A"
请不要同时用C++和C++来标记这些问题。这些是不同的语言,有不同的IO策略。决定你想要哪一个。@ J.S.GugStdt:我接受两种语言的答案,两个世界的解决方案都可以。程序中的NG文字,可以逃出字符“代码>”,这个\NIS\N“/CODE”实际上存储了字符串中的<代码> \n <代码>。否则可能不。不介意,您刚才在说ASCII格式。C<代码> Prtff <代码>(家庭)和C++ <代码> IoStry不应该与实际的“字符串”内容有任何问题。(我之前的评论与ANSI转义有关)只要你能nul终止数组,你就应该能够在
printf
或cout
中使用它。我对下面的printf没有任何问题(“这个\nis\na\\test\n\n她说,\”你好吗?\“\n”)
如果您的字符数组包含以nul结尾的字符串,那么简单的printf(ptr_to_your_数组)
工作正常。是的,这就是我需要的。我想知道是否没有更多的标准内容,但显然没有。我添加了处理转义的代码。小的改进:isalnum((未签名字符)*s)< /代码>处理讨厌的否定<代码> *S\<代码>和<代码> \\x%02x > <代码> > \x%02HHX“<代码> > ySavaDouthST字符,如<代码>!'<代码>和<代码> > < <代码>可打印,但使用此函数替换。您认为那些是“特殊的”吗?也是?如果一个特殊字符后跟一个作为字符串一部分的十六进制数字,则这种方法不起作用。例如,“?一个”
将被打印为“\x3fa”
在另一端将被读取为一个单字符代码。@JensGustedt:这是一个糟糕的设计决策,它妨碍了数字转义符和打印字符的安全混合,因为没有结尾分隔符。如果一个特殊字符后面跟一个十六进制数字,这是字符串的一部分,这种方法就不起作用。例如“\015a”
将打印为“\x0da”
在另一端将被读取为一个单字符代码。这也隐含着编码是ASCII。但是,switch
语句中列出的所有特殊情况都不触发。@JensGustedt:我已改为八进制转义。我不介意不可移植性。您的整个案例系列仍然是c完全无用。许多平台使用有符号的字符字符c=-1;printf(\\%03o,c);
可以打印“\3777777”
。最好确保字符作为无符号字符传递或使用“\\%03hho”
。是否保证此字符串中断也会终止十六进制值?@YvesDaoust Yes。在C源代码中,使用char s[]=“\xB”“ABC\0004\1”;
,s
成为一个包含char
的数组8,其值为11,'A','B',C',0',4',1,0。字符串文字的两部分合并在一起,但十六进制转义序列以“
@chus:我没有找到有关这方面的信息;人们可能想知道字符串的解析是在粘贴之前还是之后进行的。