2013年5月14日火曜日

開発環境

プログラミング言語C 第2版 ANSI規格準拠 (B.W. カーニハン D.M. リッチー (著)、 石田 晴久 (翻訳)、共立出版)の第5章(ポインタと配列)、5.11(関数へのポインタ)、演習5-17を解いてみる。

その他参考書籍

演習 5-17.

コード

sample.c

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

#define MAXLINES 5000
#define MAXLEN 1000
#define MAXSTOR 5000
#define ALLOCSIZE 10000
#define NUMERIC 1
#define REVERSE 2
#define FOLD 4
#define DIR 8

int readlines(char *lineptr[], int nlines);
int my_getline(char *, int);
char *alloc(int);
void my_qsort(void *lineptr[], int left, int right,
           int (*comp)(void *, void*));
int numcmp(char *, char *);
int fold_strcmp(char *, char *);
int dir_strcmp(char *, char *);
int fold_dir_strcmp(char *, char *);
void swap(void *v[], int, int);
void substr(char *, char *);
int my_strcmp(char *, char *);
char allocbuf[ALLOCSIZE];
char *allocp = allocbuf;
int pos1 = 0, pos2 = 0;

int main(int argc, char *argv[])
{
    char *lineptr[MAXLINES];
    int nlines;
    char options = 0;
    char option;
    int i;
    char c;
    
    while (--argc > 0 && ((c = (*++argv)[0]) == '-' || c == '+')) {
        if (c == '-' && !isdigit(*(argv[0] + 1))) {
            while (c = *++argv[0]) {
                switch (c) {
                    case 'n':
                        options |= NUMERIC;
                        break;
                    case 'r':
                        options |= REVERSE;
                        break;
                    case 'f':
                        options |= FOLD;
                        break;
                    case 'd':
                        options |= DIR;
                        break;
                    default:
                        printf("error: option %c\n", c);
                        break;
                }
            }
        } else if (c == '+') {
            pos1 = atoi(argv[0] + 1);
        } else {
            pos2 = atoi(argv[0] + 1);
        }
    }
    if (pos2 != 0 && pos1 > pos2) {
        pos1 = 0;
        pos2 = 0;
    }
    if ((nlines = readlines(lineptr, MAXLINES)) > 0) {
        if (options & NUMERIC)
            my_qsort((void **) lineptr, 0, nlines - 1,
                  (int (*)(void *, void *)) numcmp);
        else if (options & FOLD && options & DIR)
            my_qsort((void **) lineptr, 0, nlines - 1,
                  (int (*) (void *, void *)) fold_dir_strcmp);     
        else if (options & FOLD)
            my_qsort((void **) lineptr, 0, nlines - 1,
                  (int (*) (void *, void *)) fold_strcmp);
        else if (options & DIR)
            my_qsort((void **) lineptr, 0, nlines - 1,
                  (int (*) (void *, void *)) dir_strcmp);       
        else
            my_qsort((void **) lineptr, 0, nlines - 1,
                  (int (*) (void *, void *)) my_strcmp);
        if (options & REVERSE)
            for (i = nlines - 1; i >= 0; i--)
                printf("%s\n", lineptr[i]);
        else
            for (i = 0; i < nlines; i++)
                printf("%s\n", lineptr[i]);
        return 0;
    } else {
        printf("input too big to sort\n");
        return 1;
    }
}

void my_qsort(void *v[], int left, int right,
           int (*cmp)(void *, void *))
{
    int i, last;
    
    if (left >= right)
        return;
    swap(v, left, (left + right) / 2);
    last = left;
    for (i = left+1; i <= right; i++)
        if ((*cmp)(v[i], v[left]) < 0)
            swap(v, ++last, i);
    swap(v, left, last);
    my_qsort(v, left, last-1, cmp);
    my_qsort(v, last + 1, right, cmp);
}

int readlines(char *lineptr[], int maxlines)
{
    int len, nlines;
    char *p, line[MAXLEN];
    nlines = 0;
    while ((len = my_getline(line, MAXLEN)) > 0) {
        if (nlines >= maxlines || (p = alloc(len)) == NULL)
            return -1;
        else {
            line[len - 1] = '\0';
            strcpy(p, line);
            lineptr[nlines++] = p;
        }
    }
    return nlines;
}

int my_getline(char *s, int lim)
{
    int c;
    char *t = s;
    
    while (--lim > 0 && (c = getchar()) != EOF && c != '\n')
        *s++ = c;
    if (c == '\n')
        *s++ = c;
    *s = '\0';
    return s - t;
}

char *alloc(int n)
{
    if (allocbuf + ALLOCSIZE - allocp >= n) {
        allocp += n;
        return allocp - n;
    } else 
        return 0;
}

int numcmp(char *s, char *t)
{
    double v1, v2;
    char sub_s[MAXLEN], sub_t[MAXLEN];
    if (pos1 != 0 || pos2 != 0) {
        substr(sub_s, s);
        substr(sub_t, t);
    } else {
        strcpy(sub_s, s);
        strcpy(sub_t, t);
    }
    v1 = atof(sub_s[0]);
    v2 = atof(sub_t[0]);
    if (v1 < v2)
        return -1;
    else if (v1 > v2)
        return 1;
    else
        return 0;
}

int fold_strcmp(char *s, char *t)
{
    char sub_s[MAXLEN], sub_t[MAXLEN];
    int i;
    if (pos1 != 0 || pos2 != 0) {
        substr(sub_s, s);
        substr(sub_t, t);
    } else {
        strcpy(sub_s, s);
        strcpy(sub_t, t);
    }
    for (i = 0; tolower(sub_s[i]) == tolower(sub_t[i]); i++)
        if (sub_s[i] == '\0')
            return 0;
    return tolower(sub_s[i]) - tolower(sub_t[i]);
}

int my_strcmp(char *s, char *t)
{
    char sub_s[MAXLEN], sub_t[MAXLEN];
    int i;
    if (pos1 != 0 || pos2 != 0) {
        substr(sub_s, s);
        substr(sub_t, t);
    } else {
        strcpy(sub_s, s);
        strcpy(sub_t, t);
    }
    for (; sub_s[i] == sub_t[i]; i++)
        if (sub_s[i] == '\0')
            return 0;
    return sub_s[i] - sub_t[i];
}

int dir_strcmp(char *s, char *t)
{
    char sub_s[MAXLEN], sub_t[MAXLEN];
    int i, j;
    if (pos1 != 0 || pos2 != 0) {
        substr(sub_s, s);
        substr(sub_t, t);
    } else {
        strcpy(sub_s, s);
        strcpy(sub_t, t);
    }
    i = j = -1;
    do {
        i++;
        j++;
        while (!(isalnum(sub_s[i]) || sub_s[i] == ' ' || sub_s[i] == '\0'))
            i++;
        while (!(isalnum(sub_t[j]) || sub_t[j] == ' ' || sub_t[j] == '\0'))
            j++;
        if (sub_s[i] == sub_t[j] && sub_s[i] == '\0')
            return 0;
    } while (sub_s[i] == sub_t[j]);
    return sub_s[i] - sub_t[j];
}

int fold_dir_strcmp(char *s, char *t)
{
    char sub_s[MAXLEN], sub_t[MAXLEN], a, b;
    int i, j;
    if (pos1 != 0 || pos2 != 0) {
        substr(sub_s, s);
        substr(sub_t, t);
    } else {
        strcpy(sub_s, s);
        strcpy(sub_t, t);
    }
    i = j = 0;
    do {    
        while (!(isalnum(sub_s[i]) || sub_s[i] == ' ' || sub_s[i] == '\0'))
            i++;
        while (!(isalnum(sub_t[j]) || sub_t[j] == ' ' || sub_t[j] == '\0'))
            j++;
        a = tolower(sub_s[i]);
        b = tolower(sub_t[j]);
        i++;
        j++;
        if (a == b && a == '\0')
            return 0;
    } while (a == b);
    return a - b;
}

void swap(void *v[], int i, int j)
{
    void *temp;
    temp = v[i];
    v[i] = v[j];
    v[j] = temp;
}

void substr(char *str, char *s)
{
    int i, j, len;
    len = strlen(s);
    if (pos2 != 0 && len > pos2)
        len = pos2;
    for (i = 0, j = pos1; j < len; i++, j++)
        str[i] = s[j];
    str[i] = '\0';
}

入出力結果(Terminal)

$ cat sample.txt
Ah Love! could you and I with Fate conspire
To grasp this sorry Scheme of Things entire,
Would not we shatter it to bits -- and then
Re-mould it nearer to the Heart's Desire!
ah love! could you and i with fate conspire
to grasp this sorry scheme of things entire,
would not we shatter it to bits -- and then
re-mould it nearer to the heart's desire!
!@#$%Ah Love! could you and I with Fate conspire
!@#$%To grasp this sorry Scheme of Things entire,
!@#$%Would not we shatter it to bits -- and then
!@#$%Re-mould it nearer to the Heart's Desire!
!@#$%ah love! could you and i with fate conspire
!@#$%to grasp this sorry scheme of things entire,
!@#$%would not we shatter it to bits -- and then
!@#$%re-mould it nearer to the heart's desire!
$ cat sample.txt | ./a.out
!@#$%Ah Love! could you and I with Fate conspire
!@#$%Re-mould it nearer to the Heart's Desire!
!@#$%To grasp this sorry Scheme of Things entire,
!@#$%Would not we shatter it to bits -- and then
!@#$%ah love! could you and i with fate conspire
!@#$%re-mould it nearer to the heart's desire!
!@#$%would not we shatter it to bits -- and then
Ah Love! could you and I with Fate conspire
Re-mould it nearer to the Heart's Desire!
To grasp this sorry Scheme of Things entire,
Would not we shatter it to bits -- and then
ah love! could you and i with fate conspire
!@#$%to grasp this sorry scheme of things entire,
re-mould it nearer to the heart's desire!
would not we shatter it to bits -- and then
to grasp this sorry scheme of things entire,
$ cat sample.txt | ./a.out -r
to grasp this sorry scheme of things entire,
would not we shatter it to bits -- and then
re-mould it nearer to the heart's desire!
!@#$%to grasp this sorry scheme of things entire,
ah love! could you and i with fate conspire
Would not we shatter it to bits -- and then
To grasp this sorry Scheme of Things entire,
Re-mould it nearer to the Heart's Desire!
Ah Love! could you and I with Fate conspire
!@#$%would not we shatter it to bits -- and then
!@#$%re-mould it nearer to the heart's desire!
!@#$%ah love! could you and i with fate conspire
!@#$%Would not we shatter it to bits -- and then
!@#$%To grasp this sorry Scheme of Things entire,
!@#$%Re-mould it nearer to the Heart's Desire!
!@#$%Ah Love! could you and I with Fate conspire
$ cat sample.txt | ./a.out -f
!@#$%Ah Love! could you and I with Fate conspire
!@#$%ah love! could you and i with fate conspire
!@#$%re-mould it nearer to the heart's desire!
!@#$%Re-mould it nearer to the Heart's Desire!
!@#$%To grasp this sorry Scheme of Things entire,
!@#$%to grasp this sorry scheme of things entire,
!@#$%Would not we shatter it to bits -- and then
!@#$%would not we shatter it to bits -- and then
Ah Love! could you and I with Fate conspire
ah love! could you and i with fate conspire
re-mould it nearer to the heart's desire!
Re-mould it nearer to the Heart's Desire!
to grasp this sorry scheme of things entire,
To grasp this sorry Scheme of Things entire,
would not we shatter it to bits -- and then
Would not we shatter it to bits -- and then
$ cat sample.txt | ./a.out -d
!@#$%Ah Love! could you and I with Fate conspire
Ah Love! could you and I with Fate conspire
Re-mould it nearer to the Heart's Desire!
!@#$%Re-mould it nearer to the Heart's Desire!
To grasp this sorry Scheme of Things entire,
!@#$%To grasp this sorry Scheme of Things entire,
Would not we shatter it to bits -- and then
!@#$%Would not we shatter it to bits -- and then
ah love! could you and i with fate conspire
!@#$%ah love! could you and i with fate conspire
re-mould it nearer to the heart's desire!
!@#$%re-mould it nearer to the heart's desire!
!@#$%to grasp this sorry scheme of things entire,
to grasp this sorry scheme of things entire,
!@#$%would not we shatter it to bits -- and then
would not we shatter it to bits -- and then
$ cat sample1.txt
eeeeeabcdeaaaaa
aaaaabcdeabbbbb
dddddcdeabccccc
bbbbbdeabcddddd
ccccceabcdeeeee
$ cat sample1.txt | ./a.out +1
aaaaabcdeabbbbb
ccccceabcdeeeee
bbbbbdeabcddddd
dddddcdeabccccc
eeeeeabcdeaaaaa
$ cat sample1.txt | ./a.out +5
eeeeeabcdeaaaaa
aaaaabcdeabbbbb
dddddcdeabccccc
bbbbbdeabcddddd
ccccceabcdeeeee
$ cat sample1.txt | ./a.out +6
aaaaabcdeabbbbb
ccccceabcdeeeee
eeeeeabcdeaaaaa
dddddcdeabccccc
bbbbbdeabcddddd
$ cat sample1.txt | ./a.out +7
aaaaabcdeabbbbb
eeeeeabcdeaaaaa
ccccceabcdeeeee
bbbbbdeabcddddd
dddddcdeabccccc
$ cat sample1.txt | ./a.out +8
dddddcdeabccccc
eeeeeabcdeaaaaa
bbbbbdeabcddddd
aaaaabcdeabbbbb
ccccceabcdeeeee
$ cat sample1.txt | ./a.out +9
aaaaabcdeabbbbb
dddddcdeabccccc
bbbbbdeabcddddd
eeeeeabcdeaaaaa
ccccceabcdeeeee
$ cat sample1.txt | ./a.out +10
eeeeeabcdeaaaaa
aaaaabcdeabbbbb
dddddcdeabccccc
bbbbbdeabcddddd
ccccceabcdeeeee
$ cat sample1.txt | ./a.out +11
eeeeeabcdeaaaaa
aaaaabcdeabbbbb
dddddcdeabccccc
bbbbbdeabcddddd
ccccceabcdeeeee
$ cat sample1.txt | ./a.out -1
aaaaabcdeabbbbb
ccccceabcdeeeee
bbbbbdeabcddddd
dddddcdeabccccc
eeeeeabcdeaaaaa
$ cat sample1.txt | ./a.out +5 -1
aaaaabcdeabbbbb
bbbbbdeabcddddd
ccccceabcdeeeee
dddddcdeabccccc
eeeeeabcdeaaaaa
$ cat sample1.txt | ./a.out +5 -10
eeeeeabcdeaaaaa
aaaaabcdeabbbbb
dddddcdeabccccc
bbbbbdeabcddddd
ccccceabcdeeeee
$ cat sample1.txt | ./a.out +5 -100
eeeeeabcdeaaaaa
aaaaabcdeabbbbb
dddddcdeabccccc
bbbbbdeabcddddd
ccccceabcdeeeee
$

0 コメント:

コメントを投稿