開発環境
- OS X Mavericks - Apple(OS)
- Emacs (CUI)、BBEdit - Bare Bones Software, Inc. (GUI) (Text Editor)
- C (プログラミング言語)
- Clang (コンパイラ)
C実践プログラミング 第3版 (Steve Oualline (著)、 望月 康司 (監訳) (翻訳)、谷口 功 (翻訳)、オライリー・ジャパン)のⅢ部(高度なプログラミング概念)の17章(高度なポインタ)、17-12(プログラミング実習)、実習17-1.を解いてみる。
その他参考書籍
- プログラミング言語C 第2版 ANSI規格準拠 (B.W. カーニハン D.M. リッチー (著)、 石田 晴久 (翻訳)、共立出版)
- プログラミング言語Cアンサー・ブック 第2版 (クロビス・L.トンド、スコット・E.ギンペル(著)、矢吹 道郎(翻訳))
17-12(プログラミング実習)、実習17-1.
コード
sample.c
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
struct node{
char *word;
int i;
int linenos[100];
struct node *left;
struct node *right;
};
static struct node *root = NULL;
static int current_lineno = 1;
void memory_error(void)
{
fprintf(stderr, "Error:Out of memory\n");
exit (8);
}
void add_list(struct node *node, int n)
{
node->linenos[node->i] = n;
node->i = node->i + 1;
}
void print_lineno(struct node *node)
{
int j;
for(j = 0; j < node->i; j++){
printf("%d ", node->linenos[j]);
}
printf("\n");
}
char *save_string(char *string)
{
char *new_string;
new_string = malloc((unsigned) (strlen(string) + 1));
if (new_string == NULL){
memory_error();
}
strcpy(new_string, string);
return (new_string);
}
void enter(struct node **node, char *word)
{
int result;
char *save_string();
void memory_error();
void add_list(struct node *node, int n);
if ((*node) == NULL){
(*node) = malloc(sizeof(struct node));
if ((*node) == NULL){
memory_error();
}
(*node)->word = save_string(word);
add_list((*node), current_lineno);
(*node)->left = NULL;
(*node)->right = NULL;
return;
}
result = strcmp((*node)->word, word);
if (result == 0){
add_list((*node), current_lineno);
return;
}
if (result < 0){
enter(&(*node)->right, word);
} else {
enter(&(*node)->left, word);
}
}
void scan(char *name)
{
char word[100];
int index;
int ch;
FILE *in_file;
in_file = fopen(name, "r");
if (in_file == NULL){
fprintf(stderr, "Error:Unable to open %s\n", name);
exit(8);
}
while (1){
while(1){
ch = fgetc(in_file);
if (ch == '\n'){
current_lineno++;
}
if(isalpha(ch) || (ch == EOF)){
break;
}
}
if (ch == EOF){
break;
}
word[0] = ch;
for (index = 1; index < sizeof(word); ++index){
ch = fgetc(in_file);
if (!isalpha(ch)){
break;
}
word[index] = ch;
}
word[index] = '\0';
enter(&root, word);
}
fclose(in_file);
}
void print_tree(struct node *top)
{
if (top == NULL){
return;
}
print_tree(top->left);
printf("%-10s: ", top->word);
print_lineno(top);
print_tree(top->right);
}
int main(int argc, char *argv[])
{
if(argc != 2){
fprintf(stderr, "Error:Wrong numbr of parameters\n");
fprintf(stderr, " on the command line\n");
fprintf(stderr, "Usage is:\n");
fprintf(stderr, " words 'file'\n");
exit(8);
}
scan(argv[1]);
printf("単語 : 行\n");
print_tree(root);
return (0);
}
makefile
CC=cc CFLAGS=-g sample: sample.c $(CC) $(CFLAGS) -o sample sample.c clean: rm -f sample
入出力結果(Terminal)
$ make cc -g -o sample sample.c $ ./sample sample.c 単語 : 行 EOF : 101 105 Error : 19 92 136 FILE : 88 NULL : 14 44 57 59 64 65 91 124 Out : 19 Unable : 92 Usage : 138 Wrong : 136 add : 23 56 63 72 argc : 133 135 argv : 133 142 break : 102 106 112 ch : 87 97 98 101 101 105 108 110 111 114 char : 7 38 38 40 51 54 83 85 133 command : 137 ctype : 2 current : 15 63 72 99 d : 33 else : 78 enter : 51 77 79 117 error : 17 45 55 60 exit : 20 93 140 fclose : 119 fgetc : 97 110 file : 88 90 91 97 110 119 139 fopen : 90 for : 32 109 fprintf : 19 92 136 137 138 139 h : 1 2 3 4 i : 8 25 26 26 32 if : 44 57 59 71 76 91 98 101 105 111 124 135 in : 88 90 91 97 110 119 include : 1 2 3 4 index : 86 109 109 109 114 116 int : 8 9 15 23 31 53 56 86 87 133 133 is : 138 isalpha : 101 111 j : 31 32 32 32 33 left : 10 64 79 127 line : 137 lineno : 15 29 63 72 99 129 linenos : 9 25 33 list : 23 56 63 72 main : 133 malloc : 42 58 memory : 17 19 45 55 60 n : 19 23 25 35 56 92 98 136 137 138 139 143 name : 83 90 92 new : 40 42 44 47 48 node : 6 10 11 14 23 23 25 25 26 26 29 29 32 33 51 51 56 56 57 58 58 59 62 63 64 65 69 72 77 79 122 numbr : 136 of : 19 136 on : 137 open : 92 parameters: 136 print : 29 122 127 129 130 144 printf : 33 35 128 143 r : 90 result : 53 69 71 76 return : 48 66 73 125 145 right : 11 65 77 130 root : 14 117 144 s : 92 128 save : 38 54 62 scan : 83 142 sizeof : 58 109 static : 14 15 stderr : 19 92 136 137 138 139 stdio : 1 stdlib : 4 strcmp : 69 strcpy : 47 string : 3 38 38 40 42 42 44 47 47 48 54 62 strlen : 42 struct : 6 10 11 14 23 29 51 56 58 122 the : 137 to : 92 top : 122 124 127 128 129 130 tree : 122 127 130 144 unsigned : 42 void : 17 17 23 29 51 55 56 83 122 while : 95 96 word : 7 51 62 62 69 69 77 79 85 108 109 114 116 117 128 words : 139 $
行数の格納にはリンクリストを使った方がいいけど、途中でポインタとかで頭がごちゃごちゃしてきたので、とりあえず通常の配列に格納。もっとポインタ、リンクリストに慣れたら配列をリンクリストに置き換えてみることに。
0 コメント:
コメントを投稿