読者です 読者をやめる 読者になる 読者になる

プログラミング言語 C 3.3

c k&r


a-zなんかを a....zに展開する関数 expand(s1, s2)を書けという問題。s1がソースで
s2がデスティネーションです。難しいと思ったが結構すぐできましたね。問題がある
かもしれないですね。

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>

static void expand(char *s1, char *s2);
static int is_same_type(int a, int b);
static void test_expand();

int
main(void)
{
     test_expand();
}

static void
test_expand()
{
     char dest[2048];

     expand("a-e", dest);
     assert(!strcmp(dest, "abcde"));

     expand("a-b-c", dest);
     assert(!strcmp(dest, "abc"));

     expand("a-z0-9", dest);
     assert(!strcmp(dest, "abcdefghijklmnopqrstuvwxyz0123456789"));

     expand("-a-z-", dest);
     assert(!strcmp(dest, "-abcdefghijklmnopqrstuvwxyz-"));
}

static void
expand(char *s1, char *s2)
{
     int i, j;
     char k;
     int start, end;

     i = 0;
     j = 0;
     while (s1[i] != '\0') {
          if (i >= 1 && s1[i] == '-') {
               start = s1[i - 1];
               end   = s1[i + 1];

               if (end == '\0' || !is_same_type(start, end) || start >= end) {
                    s2[j++] = '-';
               }
               else {
                    j--;
                    for (k = start; k <= end; k++) {
                         s2[j++] = k;
                    }
                    i++;
               }
          }
          else {
               s2[j++] = s1[i];
          }
          i++;
     }

     s2[j] = '\0';
}

static int
is_same_type(int a, int b)
{
     if (islower(a) && islower(b)) {
          return 1;
     }
     else if(isupper(a) && isupper(b)) {
          return 1;
     }
     else if(isdigit(a) && isdigit(b)) {
          return 1;
     }
     else {
          return 0;
     }
}