2013年8月23日金曜日

開発環境

プログラミング言語C 第2版 ANSI規格準拠 (B.W. カーニハン D.M. リッチー (著)、 石田 晴久 (翻訳)、共立出版)の第6章(構造体)、6.4(構造体へのポインタ)、6.5(自己参照的構造体)、演習6-2を解いてみる。

その他参考書籍

演習 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 コメント:

コメントを投稿