BCC32Cを使ってみた 本文へジャンプ

フリーウエア利用5  MeCab その2

ホーム プログラミング メニュー 前へ 
MeCabの応用

MeCabのサンプルプログラムを改造して、ファイルを読み込んで1行ごとに分かち書きにするプログラムを作成します。
文章の例は、SQLiteその3で使った日本国憲法です。各行はインデックス・キーと条文があるので、条文の部分を分かち書きして、インデックス・キーと条文(分かち書き)のファイルにします。

実例

コンパイル結果は@です。ソースプログラムがAです、実行結果がBで、できたファイルを表示したものがCです。

@コンパイル結果



Aソースプログラム

// -------------------------------------------------
// tagger.c  
//          2023/11/07 Kimio Nakamura
//    ファイルを読み込んで、分かち書きに入れ替える。
//    ・入力ファイル(デフォルト名、input.txt)は、1行目は
//     タイトル行、2行目以降は、インデックスとデータ文で
//     TABで区切る。
//    ・Mecabを使って、データ文を分かち書きに入れ替える。
// -------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

#include "mecab.h"

#define CHECK(eval) if (! eval) { \
    fprintf (stderr, "Exception:%s\n", mecab_strerror (mecab)); \
    mecab_destroy(mecab); \
    return -1; }

               // デフォルト区切り文字はカンマ
#define TAB 0x09
#define LF 0x0a
#define CR 0x0d

// =============================================================
//   Name     : int main(int argc, char **argv)
//   Usage    : メイン関数
//   Parameter: なし
//   Return   : なし
// =============================================================
int main( int argc, char **argv )
{
  mecab_t *mecab;
  const mecab_node_t *node;
  char arg[500]="";

  char in_fname[500]  = "input.txt";
  char out_fname[500]  = "output.txt";

  char record[50000];

  char temp_s1[5000];
  char temp_s2[15000];

  int count;
  int i , j;
                          // 入力ファイル名、作成DB名入力
  fprintf(stdout , "--------------------------------------\n");
  fprintf(stdout ,"入力ファイル名(%s):", in_fname);
  scanf(  "%s", in_fname );

  fprintf(stdout ,"出力ファイル名(%s):", out_fname);
  scanf(  "%s", out_fname  );

  FILE *fp_in;
  FILE *fp_out;
                      // 入力ファイル、チェック
  if((fp_in = fopen(in_fname , "rt" ))==NULL) {
    fprintf(stdout,"Input File open error %s\n", in_fname);
    return -1;
  }
                      // 出力ファイル、チェック
  if((fp_out = fopen(out_fname , "wt" ))==NULL) {
    fprintf(stdout,"output File open error %s\n", out_fname);
    return -1;
  }
                        // 1行目を読んで、書き込む
  if(fgets(record , 5000 , fp_in)==NULL) return 0;
//  fprintf(fp_out ,"%s\t\n" , record);
  fprintf(fp_out ,"%s" , record);
                        // Create tagger object
  mecab = mecab_new2(arg);
  CHECK(mecab);

  count=0;
  while(1){
                            // 1レコードごと読み込み
    if(kbhit()!=0)break;
    if(fgets(record,50000,fp_in)==NULL)break;
                            // インデックス部分
    strcpy(temp_s1, "");
    i=0;
    j=0;
    while(1){
      if(record[j] == TAB ){
        temp_s1[i]='\0';
        j++;
        break;
      }
      else {
        temp_s1[i] = record[j];
        i++ ;
        j++ ;
      }
    }
                            // 条文部分
    strcpy(temp_s2, "");
    i=0;
    while(1){
      if(record[j] == TAB||record[j] == CR || record[j] == LF){
        temp_s2[i]='\0';
        j++;
        break;
      }
      else {
        temp_s2[i] = record[j];
        i++ ;
        j++ ;
      }
    }

    if(strlen( temp_s1 ) == 0)continue;

    fprintf(fp_out ,"%s\t" , temp_s1);

    node = mecab_sparse_tonode(mecab, temp_s2);
    for (; node != NULL; node = node->next) {
      if (node->stat == MECAB_NOR_NODE || 
                   node->stat == MECAB_UNK_NODE) {
        fprintf( fp_out , "%.*s ", 
               sizeof(char) * node->length , node->surface);
      }
    }
    fprintf( fp_out , "\n");
      
  }

  fprintf(stdout , "----------------------------------------\n");
  fclose(fp_in);
  return 0;
}

B実行結果


D作成結果




戻る