フリーウエア利用5 MeCab その2
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作成結果

|