開発環境
- OS X Lion - Apple(OS)
- Emacs、BBEdit - Bare Bones Software, Inc. (Text Editor)
- プログラミング言語: C
- Clang (コンパイラ)
プログラミング言語C 第2版 ANSI規格準拠 (B.W. カーニハン D.M. リッチー (著)、 石田 晴久 (翻訳)、共立出版)の第5章(ポインタと配列)、5.11(関数へのポインタ)、演習5-17を解いてみる。
その他参考書籍
- プログラミング言語Cアンサー・ブック 第2版 (クロビス・L.トンド、スコット・E.ギンペル(著)、矢吹 道郎(翻訳))
演習 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 コメント:
コメントを投稿