K&Rを読もう(14) 演習 1-21 スマートタブ

GNUインデント

世の中には様々なインデント方式がある。その中でも最も奇妙なインデント方式がGNUであろうと思う。

最初にGNU方式を目にしたときはハァ?ナンダコレ?などと思ったが、今はそのインデント方式が少し理解できるようになった。

スマートタブ

さて、今回はGNUで使われているインデント方式であるスマートタブに変換せよという問題です。

「8個スペースが続いたら、tabに変換する」

という奇妙なインデント方式。tabとスペースを混在させて使っている所がポイント。


今回のソースはGNU方式で書いてみたぞ。

#include <stdio.h>
#include <stdlib.h>

// #define TAB "\t"
// #define TAB ">-------"
#define TAB "\033[1;30m>-------\033[0m"

int
main (void)
{
  int c;
  int count = 0;

  while ((c = getchar ()) != EOF)
    {
      if (c == ' ')
        {
          if (++count >= 8)
            {
              printf (TAB);
              count = 0;
            }
        }
      else
        {
          for (; count > 0; count--)
            putchar (' ');

          if (c == '\t')
            printf (TAB);
          else
            putchar (c);
        }
    }
  exit (EXIT_SUCCESS);
}

うっは。読めねぇ・・・。

さて、ソースは全てスペースで構成されているので、スマートタブに変換してみる。

% ./ex-1-21 < ex-1-21.c
#include <stdio.h>
#include <stdlib.h>

// #define TAB "\t"
// #define TAB ">-------"
#define TAB "\033[1;30m>-------\033[0m"

int
main (void)
{
  int c;
  int count = 0;

  while ((c = getchar ()) != EOF)
    {
      if (c == ' ')
>-------{
>-------  if (++count >= 8)
>-------    {
>-------      printf (TAB);
>-------      count = 0;
>-------    }
>-------}
      else
>-------{
>-------  for (; count > 0; count--)
>-------    putchar (' ');

>-------  if (c == '\t')
>-------    printf (TAB);
>-------  else
>-------    putchar (c);
>-------}
    }
  exit (EXIT_SUCCESS);
}

GNUインデント完成〜。

可視化するとGNUインデントの変態っぷりがよくわかると思う。

こいつら絶対頭おかしいよ!!

追記

本来の問題は、スペーシングを最小にしろ。という事なので、スペースの後にtabがあった場合の処理も追加したほうがいいと思う。

  >-----

tabの長さは可変なので真面目にやると大変。