带有特殊字符的字符串的控制台输出
Console output of strings with special characters
是否有或多或少的标准方法来输出包含特殊字符的字符串,例如 ASCII 控制代码,输出是有效的 C/C++ 文字字符串,带有转义序列?
预期输出示例:This\nis\na\test\n\nShe said, \"How are you?\"\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;
}
}
}
(注意 c < ' ' || c > '~'
的潜在不可移植性,我想避免任何库引用)。
清楚地打印转义字符串很棘手。
问题包括
- 控制字符和空字符。
- 转义转义字符。
- 否定
char
.
十六进制转义序列没有指定的长度限制。八进制数限制为3位。
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 位的少数机器上是一个问题。这可以在 string 级别使用十六进制转义序列来处理,而不是在 char
by char
的基础上处理,因为十六进制转义序列需要限制。示例:
input 2 `char`: A
// v----- intervening space
output text including ": "\x1" "A"
是否有或多或少的标准方法来输出包含特殊字符的字符串,例如 ASCII 控制代码,输出是有效的 C/C++ 文字字符串,带有转义序列?
预期输出示例:This\nis\na\test\n\nShe said, \"How are you?\"\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;
}
}
}
(注意 c < ' ' || c > '~'
的潜在不可移植性,我想避免任何库引用)。
清楚地打印转义字符串很棘手。
问题包括
- 控制字符和空字符。
- 转义转义字符。
- 否定
char
. 十六进制转义序列没有指定的长度限制。八进制数限制为3位。
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 位的少数机器上是一个问题。这可以在 string 级别使用十六进制转义序列来处理,而不是在 char
by char
的基础上处理,因为十六进制转义序列需要限制。示例:
input 2 `char`: A
// v----- intervening space
output text including ": "\x1" "A"