2013年8月19日月曜日

開発環境

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

その他参考書籍

演習 5-16.

コード

sample.c

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

#define NUM 1
#define REV 2
#define FOLD 4
#define DIR 8

#define MAXLINES 5000
char *lineptr[MAXLINES];

int readlines(char *[], int);
void writelines(char *[], int, int);

void my_qsort(void *[], int, int, int (*comp)(void *, void*));
int numcmp(char *, char *);
int strcmp_d(char *, char *);
int strcmp_i(char *, char *);

static int option = 0;

int main(int argc, char *argv[])
{
    int nlines;
    char c;
    
    while (--argc > 0 && (*++argv)[0] == '-') {
        while (c = *++argv[0]) {
            switch(c) {
                case 'n':
                    option |= NUM;
                    break;
                case 'r':
                    option |= REV;
                    break;
                case 'f':
                    option |= FOLD;
                    break;
                case 'd':
                    option |= DIR;
                    break;
                default:
                    printf("invalid option %c\n", c);
                    break;
            }
        }
    }
    if((nlines = readlines(lineptr, MAXLINES)) >= 0) {
        my_qsort((void **) lineptr, 0, nlines - 1,
            (int (*)(void *, void*))((option & NUM) ? numcmp:
                                     (option & DIR) ? strcmp_d:
                                     (option & FOLD) ? strcmp_i : strcmp));
        writelines(lineptr, nlines, option);
        return 0;
    } else {
        printf("input too big to sortn");
        return 1;
    }
}

void my_qsort(void *v[], int left, int right,
           int (*cmp)(void *, void *))
{
    int i, last;
    void swap(void *v[], int, int);
    
    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);
}

#include <stdlib.h>

int numcmp(char *s1, char *s2)
{
    double v1, v2;
    
    v1 = atof(s1);
    v2 = atof(s2);
    if (v1 < v2) {
        return -1;
    } else if (v1 > v2) {
        return 1;
    }
    return 0;
}

#include <ctype.h>

int strcmp_d(char *s1, char *s2)
{
    char c1, c2;
    if (option & FOLD) {
        do {
            for(; !isalnum(*s1) && !isspace(*s1) && *s1 != '\0'; s1++)
                ;
            for(; !isalnum(*s2) && !isspace(*s2) && *s2 != '\0'; s2++)
                ;
            c1 = tolower(*s1);
            c2 = tolower(*s2);
            if (c1 == c2 && c1 == '\0') {
                return 0;
            }
            s1++;
            s2++;
        } while (c1 == c2);
        return c1 - c2;
    } 
    do {
        for(; !isalnum(*s1) && !isspace(*s1) && *s1 != '\0'; s1++)
            ;
        for(; !isalnum(*s2) && !isspace(*s2) && *s2 != '\0'; s2++)
            ;
        if (*s1 == *s2 && *s1 == '\0') {
            return 0;
        }
        c1 = *s1;
        c2 = *s2;
        s1++;
        s2++;
    } while (c1 == c2);
    return c1 - c2;
}

int strcmp_i(char *s1, char *s2)
{
    for (; tolower(*s1) == tolower(*s2); s1++, s2++) {
        if (*s1 == '\0') {
            return 0;
        }
    }
    return tolower(*s1) - tolower(*s2);
}

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

#define MAXLEN 1000
int my_getline(char *, int);
char *alloc(int);

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;
}

void writelines(char *lineptr[], int nlines, int option)
{
    int i;
    
    if (option & REV) {
        for (i = nlines - 1; i >= 0; i--) {
            printf("%s\n", lineptr[i]);
        }
    } else {
        for (i = 0; i < nlines; i++) {
            printf("%s\n", lineptr[i]);
        }
    }
}

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

#define ALLOCSIZE 10000

char allocbuf[ALLOCSIZE];
char *allocp = allocbuf;

char *alloc(int n)
{
    if (allocbuf + ALLOCSIZE - allocp >= n) {
        allocp += n;
        return allocp - n;
    } else {
        return 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!
1
5
2
4
3
!@#$%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!
$ ./a.out -d < sample.txt
1
2
3
4
5
!@#$%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
$ ./a.out -f < sample.txt
!@#$%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
1
2
3
4
5
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
$ ./a.out -df < sample.txt
1
2
3
4
5
Ah Love! could you and I with Fate conspire
ah love! could you and i with fate conspire
!@#$%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!
!@#$%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,
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
Would not we shatter it to bits -- and then
would not we shatter it to bits -- and then
$ ./a.out -fd < sample.txt
1
2
3
4
5
Ah Love! could you and I with Fate conspire
ah love! could you and i with fate conspire
!@#$%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!
!@#$%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,
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
Would not we shatter it to bits -- and then
would not we shatter it to bits -- and then
$ ./a.out -d -f < sample.txt
1
2
3
4
5
Ah Love! could you and I with Fate conspire
ah love! could you and i with fate conspire
!@#$%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!
!@#$%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,
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
Would not we shatter it to bits -- and then
would not we shatter it to bits -- and then
$ ./a.out -f -d < sample.txt
1
2
3
4
5
Ah Love! could you and I with Fate conspire
ah love! could you and i with fate conspire
!@#$%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!
!@#$%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,
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
Would not we shatter it to bits -- and then
would not we shatter it to bits -- and then
$

0 コメント:

コメントを投稿