In case code needs to write with no ambiguity, using C syntax:
#include <ctype.h>
#include <string.h>
#include <stdio.h>
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++);
}
}
Alternatively, code could
void EscapePrint(char sch) {
int ch = (unsigned char) sch;
...
}
void EscapePrints(const char *data, int length) {
while (length-- > 0) {
EscapePrint(*data++);
}
}
To use a hexadecimal-escape-sequence or a shorten octal-escape-sequence, code needs to insure that the next character does not create ambiguity. That complication does not occur in the above code as it uses 3-digit octal-escape-sequences. Amended code would be something like:
} 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);
}
}