1.ファイル名(sfn)が".txt"担っているが、C言語ではワイルドカードを指定して読み込むことはできません。
具体的な実際に存在するファイル名を指定しなければいけません。(word.txtとしました)
それともファイル名を公開したくなくて .txtとしたのでしょうか。
いずれにせよ、*.txtではエラーになります。
2.char c は一般論として、int型で確保したほうが良いです。
(getcの戻り値がint型のためです。EOFの場合、-1が返り、文字を読み込んだ場合は0~255の値が返ります)
ファイル内の文字が全てASCII(7ビット)なら、問題ありませんが、漢字を含む場合、0x80以上の文字が返り
char 型で扱うと、0x80以上の場合対応できなくなります。
(今回の場合はファイル内の文字が全てASCII(7ビット)なのでchar型でも対応は可能です)
3.char str[256]の初期化が行われていません。
4.特殊文字が出現した場合を判定するのではなく、A-Z,a-z以外の文字が出現した場合を、
区切り文字として扱うべきです。いくつか区切り文字をならべてますが、タブキー、改行コード等がいろいろ
漏れています。
従って、
①A-Z,a-zの場合、単語としてstrに格納
②上記以外の場合、strが空でなければ、tinsertを呼び出して単語登録
のようにすべきです。
5.tinsertで、p->right,p->leftがNULLの時、mallocして単語を登録しますが、
そのmallocしたアドレスが設定されていません。
6.inorderのカウントの方法がおかしいので修正しました。
以上を反映すると以下のようになります。
C
1 # include <stdio.h>
2 # include <stdlib.h>
3 # include <string.h>
4
5 struct node
6 {
7 char key [ 20 ] ; // 単語を格納
8 int count ; // 単語の登録回数(出現頻度)を格納
9 struct node * left , * right ;
10 } ;
11 typedef struct node CELL ;
12
13 CELL * tinsert ( CELL * , char * ) ; /* 2分探索木に単語を登録する関数 */
14 int inorder ( CELL * ) ; /* 間順走査を行う関数 */
15 CELL * tsearch ( CELL * , char * ) ; /* 2分探索木を探索する関数 */
16
17 int main ( void )
18 {
19 CELL * root , * p , * q ;
20 char name [ 20 ] ;
21 char sfn [ ] = "word.txt" ; //修正
22 FILE * sfp ;
23 int c ; //修正
24 char str [ 256 ] ;
25 int a , i , j = 0 ;
26 if ( ( sfp = fopen ( sfn , "r" ) ) == NULL )
27 {
28 printf ( "File open error \n" ) ;
29 exit ( 1 ) ;
30 }
31
32 printf ( "\n**************************\n" ) ;
33 printf ( "入力ファイル名: %s\n\n" , sfn ) ;
34 //追加開始
35 for ( i = 0 ; i < 20 ; i ++ )
36 {
37 str [ i ] = '\0' ; //初期化
38 }
39 //追加終了
40 root = NULL ;
41 i = 0 ;
42 while ( ( c = fgetc ( sfp ) ) != EOF )
43 {
44 //修正開始
45 if ( ( c >= 'A' && c <= 'Z' ) || ( c >= 'a' && c <= 'z' ) )
46 {
47 if ( c >= 'A' && c <= 'Z' )
48 c += 32 ;
49 str [ i ] = c ;
50 i ++ ;
51 continue ;
52 }
53 else
54 {
55 if ( strcmp ( str , "" ) == 0 ) continue ;
56 }
57 //修正終了
58 if ( j == 0 ) //修正
59 {
60 printf ( "%s\n" , str ) ; //修正
61 root = tinsert ( root , str ) ;
62 j ++ ;
63 for ( i = 0 ; i < 20 ; i ++ )
64 {
65 str [ i ] = '\0' ; //初期化
66 }
67 i = 0 ;
68 }
69 else if ( j == 1 )
70 {
71 printf ( "%s\n" , str ) ; //修正
72 q = tinsert ( root , str ) ;
73 for ( i = 0 ; i < 20 ; i ++ )
74 {
75 str [ i ] = '\0' ; //初期化
76 }
77 i = 0 ;
78 }
79 }
80
81 printf ( "*** 単語の出現頻度 ***\n" ) ;
82
83 a = inorder ( root ) ;
84 printf ( "%d種類の単語を登録\n" , a ) ;
85
86 while ( 1 )
87 {
88 printf ( "\n単語, または00を入力して下さい(00なら終了します): " ) ; /*** 00 が入力されるまで繰り返す***/
89 scanf ( "%s" , name ) ;
90 if ( strcmp ( name , "00" ) == 0 )
91 break ;
92 else
93 {
94 q = tsearch ( root , name ) ;
95 if ( q != NULL )
96 printf ( "%sの出現頻度: %d\n" , name , q -> count ) ;
97 }
98 }
99 printf ( "終了します.\n" ) ;
100
101 fclose ( sfp ) ;
102
103 return 0 ;
104 }
105
106 CELL * tinsert ( CELL * p , char * name )
107 {
108 int ind ;
109 CELL * wp ; //追加
110 if ( p == NULL )
111 {
112 p = ( CELL * ) malloc ( sizeof ( CELL ) ) ;
113 strcpy ( p -> key , name ) ;
114 p -> count = 1 ;
115 p -> left = p -> right = NULL ;
116 return p ;
117 }
118 //修正開始
119 else if ( strcmp ( name , p -> key ) > 0 ) {
120 wp = tinsert ( p -> right , name ) ;
121 if ( p -> right == NULL ) {
122 p -> right = wp ;
123 }
124 } else if ( strcmp ( name , p -> key ) < 0 ) {
125 wp = tinsert ( p -> left , name ) ;
126 if ( p -> left == NULL ) {
127 p -> left = wp ;
128 }
129 //修正終了
130 } else if ( strcmp ( name , p -> key ) == 0 ) {
131 p -> count += 1 ;
132 return p ;
133 }
134 }
135 int inorder ( CELL * p )
136 {
137 int count = 0 ;
138 //修正開始
139 if ( p != NULL )
140 {
141 count ++ ;
142 if ( p -> left != NULL ) {
143 count += inorder ( p -> left ) ;
144 }
145 if ( p -> right != NULL ) {
146 count += inorder ( p -> right ) ;
147 }
148 }
149 return count ;
150 //修正終了
151 }
152 CELL * tsearch ( CELL * p , char * name )
153 {
154 int ind ;
155
156 if ( p != NULL )
157 {
158 if ( strcmp ( name , p -> key ) > 0 )
159 tsearch ( p -> right , name ) ;
160 else if ( strcmp ( name , p -> key ) < 0 )
161 tsearch ( p -> left , name ) ;
162 else if ( strcmp ( name , p -> key ) == 0 )
163 return p ;
164 }
165
166 else
167 {
168 printf ( "%sの単語は登録されていません!\n" , name ) ;
169 return NULL ;
170 }
171 }
172
173