转义printf()中的所有特殊字符
是否有一种简单的方法来转义printf()
函数中的所有特殊字符?
我想知道如何做到这一点的原因是因为我打印了一些字符,其中可能包含特殊字符,如空字符( \0
)和哔声字符,我只想查看字符串的内容。
目前我正在使用以下代码
它适用于空字符。 逃脱所有特殊角色的最简单方法是什么?
int length; char* data = GetData( length ); // Fills the length as reference for( int i = 0; i < length; i++ ) { char c = data[ i ]; printf( "%c", ( c == 0 ? '\\0' : data[ i ] ) ); }
首先, '\\0'
是一个双字符文字,它应该是一个双字符串。 至于将所有特殊字符打印为转义码,您需要更多代码:
switch (data[i]) { case '\0': printf("\\0"); break; case '\n': printf("\\n"); break; /* Etc. */ default: /* Now comes the "hard" part, because not all characters here * are actually printable */ if (isprint(data[i])) printf("%c", data[i]); /* Printable character, print it as usual */ else printf("\\x%02x", data[i]); /* Non-printable character, print as hex value */ break; }
使用isprint
库函数确定字符是否可打印:
#include ... if (isprint(data[i])) printf(" %c", data[i]); // prints character else printf(" %d", data[i]); // prints code value for character
如果代码需要在没有歧义的情况下编写,请使用C语法:
#include #include #include void EscapePrint(int ch) { // Delete or adjust these 2 arrays per code's goals // All simple-escape-sequence C11 6.4.4.4 static const char *escapev = "\a\b\t\n\v\f\r\"\'\?\\"; static const char *escapec = "abtnvfr\"\'\?\\"; char *p = strchr(escapev, ch); if (p && *p) { printf("\\%c", escapec[p - escapev]); } else if (isprint(ch)) { fputc(ch, stdout); } else { // Use octal as hex is problematic reading back printf("\\%03o", ch); } } void EscapePrints(const char *data, int length) { while (length-- > 0) { EscapePrint((unsigned char) *data++); } }
或者,代码可以
void EscapePrint(char sch) { int ch = (unsigned char) sch; ... } void EscapePrints(const char *data, int length) { while (length-- > 0) { EscapePrint(*data++); } }
要使用hex转义序列或缩短八进制转义序列,代码需要确保下一个字符不会产生歧义。 上述代码中不会出现这种复杂情况,因为它使用3位八进制转义序列。 修改后的代码如下:
} else { if ((ch == 0) && (nextch < '0' || nextch > '7')) { fputs("\\0", stdout); } else if (!isxdigit((unsigned char) nextch)) { printf("\\x%X", ch); } else { // Use octal as hex is problematic reading back printf("\\%03o", ch); } }