|
構造体のwordがポインタで、
token = strtok(line, SEPARATOR);
word_table[table_size].word = token;
とすると、一見うまくいっているように見えますが、
二回目以降のfgetsでlineの内容が書き換わってしまうので問題です。
この部分は動的にメモリを確保し、strcpyで書き写してやる必要があります。
それ以外は一通りOKかと。
ただプログラムがかなり冗長です。
同じコードが複数出てきた場合は、ループの書き方を改善するとコードを減らせることが多いです。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FILENAME "test.txt" /*入力するファイル名*/
#define SEPARATOR " -,.?()'" /*単語を区切る文字*/
#define TABLESIZE 1000 /*word_tableの大きさ*/
struct word_count {
char *word; /*単語*/
int count; /*頻度*/
};
int main() {
FILE *fp;
struct word_count word_table[TABLESIZE]; /*単語と頻度を格納する配列*/
char line[256], *token;
int i, table_size, find;
table_size = 0;
/*ファイル入力にエラーが生じた場合*/
if ((fp = fopen(FILENAME, "r")) == NULL) {
printf("file open error!!\n");
exit(1);
}
while(fgets(line, 256, fp) != NULL) {
token = strtok(line, SEPARATOR);
for(;token!= NULL;token = strtok(NULL, SEPARATOR)){
find = 0;
/*word_tableとの照合*/
for (i = 0; i < table_size; i++) {
/*一致する単語を見つけた場合*/
if (strcmp(token, word_table[i].word) == 0) {
word_table[i].count++;
find = 1;
break;
}
}
/*word_table中に一致する単語がなかった場合*/
if (find == 0) {
word_table[table_size].word = malloc((strlen(token)+1)*sizeof(char));
strcpy(word_table[table_size].word,token);
word_table[table_size].count = 1;
table_size++;
}
}
}
fclose(fp);
/*word_tableを出力*/
for (i = 0; i < table_size; i++) {
printf("word=%5s count=%d\n", word_table[i].word, word_table[i].count);
}
return(0);
}
|