開発環境
- 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 コメント:
コメントを投稿