演習 3-2

無職の間にK&Rを再読。演習問題の解答をさらす。解く順番は適当。

演習 3-2
改行文字やタブのような文字を目で見えるエスケープ文字 \n や \t に変換しながら、s を t にコピーするような関数 escape(s, t) を書け。switch を使うこと。逆に、エスケープ系列を実際の文字に変換する関数も書いてみよ。


Exercise 3-2
Write a function escape(s, t) that converts characters like newline and tab into visible escape sequences like \n and \t as it copies the string t to s. Use a switch. Write a function for the other direction as well, converting escape sequence into the real characters.


なんかさらっと書いてある逆に〜のほうが演習っぽくね?

#include <stdio.h>

#define ON  1
#define OFF 0

/* Answer  */
void escape(const char s[], char t[])
{
  int i, j;
  for (i = j = 0; s[i] != '\0'; i++) {
    switch (s[i]) {
    case '\n':
      t[j++] = '\\'; t[j++] = 'n';
      break;
    case '\t':
      t[j++] = '\\'; t[j++] = 't';
      break;
    case '\v':
      t[j++] = '\\'; t[j++] = 'v';
      break;
    case '\b':
      t[j++] = '\\'; t[j++] = 'b';
      break;
    case '\r':
      t[j++] = '\\'; t[j++] = 'r';
      break;
    case '\f':
      t[j++] = '\\'; t[j++] = 'f';
      break;
    case '\a':
      t[j++] = '\\'; t[j++] = 'a';
      break;
    case '\\':
      t[j++] = '\\'; t[j++] = '\\';
      break;
    case '\?':
      t[j++] = '\\'; t[j++] = '\?';
      break;
    case '\"':
      t[j++] = '\\'; t[j++] = '\"';
      break;
    case '\'':
      t[j++] = '\\'; t[j++] = '\'';
      break;
    default:
      t[j++] = s[i];
    }
  }
  t[j] = '\0';
}


void unescape(const char s[], char t[])
{
  int esc = OFF;
  int i, j;
  t[0] = s[0];
  for (i = j = 1; s[i] != '\0'; i++) {
    if (s[i-1] == '\\' && esc == OFF) {
      switch (s[i]) {
      case 'n':
        t[j - 1] = '\n';
        break;
      case 't':
        t[j - 1] = '\t';
        break;
      case 'v':
        t[j - 1] = '\v';
        break;
      case 'b':
        t[j - 1] = '\b';
        break;
      case 'r':
        t[j - 1] = '\r';
        break;
      case 'f':
        t[j - 1] = '\f';
        break;
      case 'a':
        t[j - 1] = '\a';
        break;
      case '\\':
        t[j - 1] = '\\';
        esc = ON;
        break;
      case '?':
        t[j - 1] = '\?';
        break;
      case '\'':
        t[j - 1] = '\'';
        break;
      case '"':
        t[j - 1] = '\"';
        break;
      }
    } else {
      t[j++] = s[i];
      esc = OFF;
    }
  }
  t[j] = '\0';
}



int main(void)
{
  char s[] = "\"The\tC\n\'\'Programmi\\ngo\b Language\?\a\a\"";
  char t1[100], t2[100];
  
  printf("***** origin *****\n" "[%s]\n\n", s);

  escape(s, t1);

  printf("***** escape *****\n" "[%s]\n\n", t1);

  unescape(t1, t2);
  
  printf("**** unescape ****\n" "[%s]\n\n", t2);
  
  return 0;
}