Существует ли более или менее стандартный способ вывода символьных строк, содержащих специальные символы, например управляющих кодов ASCII, таким образом, чтобы вывод представлял собой действительную литеральную строку C / C ++ с escape-последовательностями?
Пример ожидаемого результата: 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
), но это не должно быть проблемой.
Печать экранированных строк явно сложно.
Проблемы включают
char
,Шестнадцатеричная escape-последовательность не имеет определенного ограничения по длине. Восьмеричные ограничены 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);
}
}
Pedantic: восьмеричная последовательность побега — проблема редких машин, чьи char
диапазон превышает 9 бит. Это может быть обработано с помощью шестнадцатеричных экранированных последовательностей на строка уровень, а не на char
от char
Основание как шестнадцатеричные экранированные последовательности требуют ограничения. Пример:
input 2 `char`: \1 A
// v----- intervening space
output text including ": "\\x1" "A"
Если это кому-то поможет, я быстро соединил это:
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 > '~'
Я хотел избежать любой ссылки на библиотеку).