フォルダ内のすべてのtxtファイルを読み取って単語の頻度をカウントして最後に表示

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
taty

フォルダ内のすべてのtxtファイルを読み取って単語の頻度をカウントして最後に表示

#1

投稿記事 by taty » 9年前

実行
./a.out *.txt

単語の使用頻度をカウントして最後に表示したいのですがエラーになってしまいます・・・

コード:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>

typedef struct token_checker{
  char *token;
  int count;
}TOKEN_CHECKER;

int main(int argc,char* argv[]){
  FILE * fp;
  char buffer[1024];
  int numword=0;
  char * delimiter = " .,;:!?"; //除外する文字
  char * s;
  TOKEN_CHECKER *t;
  int i,k;
  int find;
  
  t=(TOKEN_CHECKER*)malloc(sizeof(TOKEN_CHECKER)*24);
  
  if(argc < 2){
    printf("Parameter error.\n");
    exit(1);
  }

  for(k=1;k<argc;k++){
    
  if((fp=fopen(argv[k],"r"))==NULL){
    printf("File open error.\n");
    exit(1);
  }
  
  while( fgets(buffer,sizeof(buffer),fp)!=NULL){
    buffer[strlen(buffer)-1]='\0';
    s = strtok(buffer,delimiter);
    if(s != NULL){
      find=0;
      for(i=1;i<=numword;i++){
	if(strcmp(s,t[i].token)==0){
	  t[i].count++;
	  find=1;
	}
      }
      if(find==0){
	numword++;
	t[numword].token=(char*)malloc(strlen(s)+1);
	strcpy(t[numword].token,s);
	t[numword].count=1;
      }
    }
    
    while((s=strtok(NULL,delimiter)) != NULL){
      find=0;
      for(i=1;i<=numword;i++){
	if(strcmp(s,t[i].token)==0){
	  t[i].count++;
	  find=1;
	}
      }
      if(find==0){
	numword++;
	t[numword].token=(char*)malloc(strlen(s)+1);
	strcpy(t[numword].token,s);
	t[numword].count=1;
      }
    }
  }
  }
 
  free(t);
  
  fclose(fp);
  
  for(i=1;i<=numword;i++){
    printf("%8s %d回\n",t[i].token,t[i].count);
    free(t[i].token);
  }
  
  exit(0);
}


アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: フォルダ内のすべてのtxtファイルを読み取って単語の頻度をカウントして最後に表示

#2

投稿記事 by みけCAT » 9年前

taty さんが書きました:

コード:

  free(t);
  
  fclose(fp);
  
  for(i=1;i<=numword;i++){
    printf("%8s %d回\n",t[i].token,t[i].count);
    free(t[i].token);
  }
freeした後のtを使用しています。これはいけませんね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 14年前

Re: フォルダ内のすべてのtxtファイルを読み取って単語の頻度をカウントして最後に表示

#3

投稿記事 by box » 9年前

taty さんが書きました: 単語の使用頻度をカウントして最後に表示したいのですがエラーになってしまいます・・・
どんなエラーが出るのですか?まずはそこからです。

また、字下げが乱れているところが何ヶ所もあって、コードが読みづらいです。
他の投稿者の方がどういう風に字下げしているか、参考になさってみてはいかがでしょう。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

かずま

Re: フォルダ内のすべてのtxtファイルを読み取って単語の頻度をカウントして最後に表示

#4

投稿記事 by かずま » 9年前

free(t); と fclose(fp); の位置が変です。
単語数 24 は少なすぎるので 4000 にしてみました。
除外する文字に、改行やタブを含めて、たくさん追加しました。

コード:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAX_WORD 4000

typedef struct token_checker {
    char *token;
    int count;
} TOKEN_CHECKER;

int main(int argc, char *argv[])
{
    FILE *fp;
    char buffer[1024];
    int numword = 0;
    const char *delimiter = " \t\r\n\".,;:!?(){}[]+*=%"; //除外する文字
    char *s;
    TOKEN_CHECKER *t;
    int i, k;
    int find;

    t = (TOKEN_CHECKER *) malloc(sizeof(TOKEN_CHECKER) * MAX_WORD);

    if (argc < 2) {
        printf("Parameter error.\n");
        exit(1);
    }

    for (k = 1; k < argc; k++) {

        if ((fp = fopen(argv[k], "r")) == NULL) {
            printf("File open error.\n");
            exit(1);
        }

        while (fgets(buffer, sizeof(buffer), fp) != NULL) {
            buffer[strlen(buffer) - 1] = '\0';
            s = strtok(buffer, delimiter);
            if (s != NULL) {
                find = 0;
                for (i = 1; i <= numword; i++) {
                    if (strcmp(s, t[i].token) == 0) {
                        t[i].count++;
                        find = 1;
                    }
                }
                if (find == 0) {
                    if (numword++ == MAX_WORD) {
                        printf("too many word\n"); exit(1);
                    }
                    t[numword].token = (char *) malloc(strlen(s) + 1);
                    strcpy(t[numword].token, s);
                    t[numword].count = 1;
                }
            }

            while ((s = strtok(NULL, delimiter)) != NULL) {
                find = 0;
                for (i = 1; i <= numword; i++) {
                    if (strcmp(s, t[i].token) == 0) {
                        t[i].count++;
                        find = 1;
                    }
                }
                if (find == 0) {
                    if (numword++ == MAX_WORD) {
                        printf("too many word\n"); exit(1);
                    }
                    t[numword].token = (char *) malloc(strlen(s) + 1);
                    strcpy(t[numword].token, s);
                    t[numword].count = 1;
                }
            }
        }
        fclose(fp);
    }
    for (i = 1; i <= numword; i++) {
        printf("%8s %d回\n", t[i].token, t[i].count);
        free(t[i].token);
    }
    free(t);
    exit(0);
}
同じことを 2度書かないようにすると、

コード:

        while (fgets(buffer, sizeof(buffer), fp) != NULL) {
            char *p;
            buffer[strlen(buffer) - 1] = '\0';
            for (p = buffer; (s = strtok(p, delimiter)) != NULL; p = NULL) {
                find = 0;
                for (i = 1; i <= numword; i++) {
                    if (strcmp(s, t[i].token) == 0) {
                        t[i].count++;
                        find = 1;
                    }
                }
                if (find == 0) {
                    numword++;
                    if (numword == MAX_WORD) {
                        printf("too many word\n"); exit(1);
                    }
                    t[numword].token = (char *) malloc(strlen(s) + 1);
                    strcpy(t[numword].token, s);
                    t[numword].count = 1;
                }
            }
        }
この掲示板では、タブは 4桁のスペースに変換されます。
投稿するときは、タブをスペースを混在させないようにしましょう。

閉鎖

“C言語何でも質問掲示板” へ戻る