When we iterate through s, we create two indexes. The first
refers to the position of the current character we are on in
s, and the second will be the next free position in
t. During every iteration, we enter a
switch
-statement. Normally, we simply copy the character,
but in case the character happens to be a newline or tab, we append the
two characters in their escape sequences. When this happens,
t's index will increment twice.
/* escape: copy string t to s and make escape sequences visible */
void escape(char s[], char t[])
{
int i, j;
for (i = j = 0; t[i] != '\0'; ++i) {
switch (t[i]) {
case '\n':
s[j++] = '\\';
s[j] = 'n';
break;
case '\t':
s[j++] = '\\';
s[j] = 't';
break;
default:
s[j] = t[i];
break;
}
++j;
}
s[j] = '\0';
}
The unescape
function works in a similar vein. We once
again use a switch
-statement, and copy the character by
default. When we come across a backslash, we enter another
switch
-statement that checks the next character. If it
happens to be n or t, we copy a newline or tab
character; otherwise, we copy the backslash and the next character.
/* unescape: copy string t to s and make visible escape sequences invisible */
void unescape(char s[], char t[])
{
int i, j;
for (i = j = 0; t[i] != '\0'; ++i) {
switch (t[i]) {
case '\\':
switch (t[++i]) {
case 'n':
s[j] = '\n';
break;
case 't':
s[j] = '\t';
break;
default:
s[j++] = '\\';
s[j] = t[i];
break;
}
break;
default:
s[j] = t[i];
break;
}
++j;
}
s[j] = '\0';
}