開発環境
- OS X Lion - Apple(OS)
- Emacs、BBEdit - Bare Bones Software, Inc. (Text Editor)
- プログラミング言語: C
- Clang (コンパイラ)
プログラミング言語C 第2版 ANSI規格準拠 (B.W. カーニハン D.M. リッチー (著)、 石田 晴久 (翻訳)、共立出版)の第6章(構造体)、6.4(構造体へのポインタ)、6.5(自己参照的構造体)、演習6-2を解いてみる。
その他参考書籍
- プログラミング言語Cアンサー・ブック 第2版 (クロビス・L.トンド、スコット・E.ギンペル(著)、矢吹 道郎(翻訳))
演習 6-2.
コード
sample.c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
struct tnode {
char *word;
int found;
struct tnode *left;
struct tnode *right;
};
#define MAXWORD 100
#define YES 1
#define NO 0
struct tnode *addtree(struct tnode *, char *, int, int *);
void treeprint(struct tnode *);
int getword(char *, int);
int main(int argc, char *argv[])
{
struct tnode *root;
char word[MAXWORD];
int found;
int n;
found = NO;
n = (--argc && (*++argv)[0] == '-') ? atoi(argv[0] + 1) : 6;
root = NULL;
while (getword(word, MAXWORD) != EOF) {
if (isalpha(word[0]) && strlen(word) >= n) {
root = addtree(root, word, n, &found);
}
found = NO;
}
treeprint(root);
return 0;
}
struct tnode *talloc(void);
int compare(char *, struct tnode *, int, int *);
struct tnode *addtree(struct tnode *p, char *w, int n, int *found)
{
int cond;
if (p == NULL) {
p = talloc();
p->word = strdup(w);
p->found = *found;
p->left = p->right = NULL;
} else if ((cond = compare(w, p, n, found)) < 0) {
p->left = addtree(p->left, w, n, found);
} else if (cond > 0) {
p->right = addtree(p->right, w, n, found);
}
return p;
}
struct tnode *talloc(void)
{
return (struct tnode *) malloc(sizeof(struct tnode));
}
int compare(char *s, struct tnode *p, int n, int *found)
{
int i;
char *t = p->word;
for (i = 0; *s == *t; i++, s++, t++) {
if (*s == '\0') {
return 0;
}
}
if (i >= n) {
*found = YES;
p->found = YES;
}
return *s - *t;
}
void treeprint(struct tnode *p)
{
if (p != NULL) {
treeprint(p->left);
if(p->found) {
printf("%s\n", p->word);
}
treeprint(p->right);
}
}
int getword(char *word, int lim)
{
int c, d, getch(void), skipcomment();
void ungetch(int);
char *w = word;
while (isspace(c = getch()))
;
if (c != EOF) {
*w++ = c;
}
if (isalpha(c) || c == '_' || c == '#') {
for (; --lim > 0; w++) {
if (!isalnum(*w = getch()) && *w != '_') {
ungetch(*w);
break;
}
}
} else if (c == '\'' || c == '"') {
for (; --lim > 0; w++) {
if ((*w = getch()) == '\\') {
*++w = getch();
} else if (*w == c) {
w++;
break;
} else if (*w == EOF) {
break;
}
}
} else if (c == '/') {
if ((d = getch()) == '*') {
c = skipcomment();
}else {
ungetch(d);
}
}
*w = '\0';
return c;
}
int skipcomment()
{
int c;
while ((c = getch()) != EOF) {
if (c == '*') {
if ((c = getch()) == '/') {
break;
}
ungetch(c);
}
}
return c;
}
#define BUFSIZE 100
char buf[BUFSIZE];
int bufp = 0;
int getch(void)
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
void ungetch(int c)
{
if (bufp >= BUFSIZE) {
printf("ungetch: too many characters\n");
} else {
buf[bufp++] = c;
}
}
入出力結果(Terminal)
$ ./a.out < sample.c $ ./a.out -6 < sample.c $ ./a.out -5 < sample.c getch getchar $ ./a.out -4 < sample.c getch getchar isalnum isalpha $ ./a.out -3 < sample.c argc argv buf bufp getch getchar getword isalnum isalpha stdio stdlib strdup string strlen struct $ ./a.out -2 < sample.c argc argv buf bufp compare cond for found getch getchar getword isalnum isalpha isspace main malloc stdio stdlib strdup string strlen struct $ ./a.out -1 < sample.c NO NULL addtree argc argv atoi break buf bufp c char compare cond ctype for found getch getchar getword i if int isalnum isalpha isspace left lim main malloc p printf return right root s sizeof skipcomment stdio stdlib strdup string strlen struct t talloc tnode treeprint w while word $
0 コメント:
コメントを投稿