#include #include #define ESCAPE_SEQS \ X('\a', 'a') X('\b', 'b') X('\f', 'f') X('\n', 'n') \ X('\r', 'r') X('\t', 't') X('\v', 'v') #define SIZE 1000 void escape(char *s, char *t); void unescape(char *s, char *t); /* runs escape and unescape on stdin, prints results*/ int main() { int i, c; char s[SIZE+1], t[2*SIZE+1]; for (i = 0; (c = getchar()) != EOF; i++) { if (i >= SIZE) { printf("warning : buffer overflow\n"); break; } s[i] = c; } s[i] = '\0'; escape(s, t); printf("--- escaped ---\n%s\n", t); unescape(t, s); printf("\n-- unescaped --\n%s", s); return 0; } /* escape: makes escape sequences visible as it copies s to t * size of t must be 2*size of s */ void escape(char *s, char *t) { for (; *s != '\0'; s++, t++) switch (*s) { #define X(e, c) case e : *(t++) = '\\'; *t = c; break; ESCAPE_SEQS #undef X default : *t = *s; break; } *t = '\0'; } /* unescape: inverse of escape */ void unescape(char *s, char *t) { for (; *s != '\0'; s++, t++) { if (*s == '\\') switch (*(s+1)) { #define X(e, c) case c : *t = e; s++; continue; ESCAPE_SEQS #undef X } *t = *s; } *t = '\0'; }