K&Rを読もう(36) 演習 3-3 aからzまで。

デジャブ?

演習 3-3

文字列s1の中のa-zのような省略記法を、それと等価な完全リストabc..xyzにしてs2の中に展開する関数expand(s1, s2)を書け。大文字、小文字、数字を許し、a-b-cやa-z0-9や-a-zのような場合も処理出来るようにせよ。先頭及び最後の-は文字とみなす。

むむぅ。ちょっと考えた。

方針

a-m-zで考えてみる。

  • a-mというのがあったら、abc...jklまで展開する。ここで「mは展開しない」のがポイント。
  • 次にm-zを展開し、mno...wxyまで展開。
  • zを出力。

「文字-文字」という続きの場合のみ展開し、その他はそのまま出力。また、z-a,z-z等を除外する。

ソース

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

#define MAX 1024

void expand(char *s, char *t, int size);

int main(void)
{
    char t[MAX];

    expand("-0-9 a-m-z A-M-Z Z-A-", t, MAX);
    printf("%s\n", t);

    return EXIT_SUCCESS;
}

void expand(char *s, char *t, int size)
{
    int i;
    char *end = t + size - 1;

    for (;*s != '\0'; s++) {
        if ((isdigit(*s) && *(s + 1) == '-' && isdigit(*(s + 2)) ||
             isalpha(*s) && *(s + 1) == '-' && isalpha(*(s + 2)))
            && *s < *(s + 2)) {
            for (i = *s ; i < *(s + 2) && t < end; i++)
                *t++ = i;
            s++;
        } else {
            if (t < end)
                *t++ = *s;
            else
                break;
        }
    }
    *t = '\0';
}

ふ・複雑。配列でやった方が良かったかも。

実行する。

-0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ Z-A-

おぉぉぉぉ。うまくいった!!