''[[FrontPage]]''
*この記事はまだ書きかけです。管理人が今後加筆していく予定ですので、参考にする場合は注意してください。
* C言語と正規表現 テストその1 [#s320671b]
テキストファイルの内容をメモリ領域にコピーし、正規表現を使って解析する。~
解析の題材として、C/C++言語ソースファイルを扱う。~
** 制約 [#dbf36254]
MFC、.NET関数を使用しないこと。~
~
~
さらによい方法が見つかればその2を書きます。
#include <stdio.h> /* */
#include <regex.h> /* C言語正規表現ライブラリ */
/* UNIX系以外では使えなさそう */
#include <string.h> /* */
#include <sys/stat.h> /* for stat() */
#include <stdlib.h> /* for malloc() */
/* */
/* */
#define RET_OK 0 /* 正常時リターンコード */
#define RET_NG -1 /* 異常時リターンコード */
#define F_NUM 40 /* 正規表現マッチポイント数 */
#define MAX_F_NAME 256 /* ロングファイル名を想定 */
#define FILE_NG -2 /* ファイル操作エラーコード */
#define INDEX_OK 0 /* 関数戻り値チェック */
#define MODE_ONE 1 /* 検索モード1(コメント) */
#define MODE_TWO 2 /* 検索モード2(#include) */
#define MODE_THREE 3 /* 検索モード3(#define) */
#define MODE_FOUR 4 /* 検索モード4(予備) */
/* */
char fileRootin( char** de_desk ); /* プロトタイプ(ファイル操作副関数) */
char styleDel( char* de_desk, unsigned char mode); /* プロトタイプ(コメント削除関数) */
char styleSearch( char* de_desk, unsigned char mode ); /* プロトタイプ(文字列検索関数) */
/* */
int main( void ) /* コンソールでの正規表現動作テスト */
{ /* */
char **desk; /* 作業領域の先頭アドレスを格納する */
int i = 0; /* カウンタ */
/* */
regex_t reg; /* for 正規表現 */
regmatch_t position[F_NUM]; /* for 正規表現 */
/* */
char regRtn = RET_OK; /* 正規表現関数戻り値 */
char index = RET_OK; /* 関数戻り値チェック用 */
char rtnCode = RET_OK; /* リターンコード */
/* */
while( 1 ) /* 無限ループ */
{ /* */
index = fileRootin( /* ファイル読み込み関数 */
desk ); /* OUT: 作業領域先頭アドレス格納アドレス */
if( INDEX_OK != index ) /* 戻り値判定 */
{ /* 正常以外の場合 */
printf("ファイルオープンエラー\n"); /* 画面表示 */
rtnCode = RET_NG; /* リターンコードをNGに設定 */
break; /* 処理終了 */
} /* */
/* */
printf("一行目のデータは\n"); /* 確認用 */
while((*desk)[i] != '\n') /* */
{ /* */
putchar((*desk)[i]); /* */
i += 1; /* */
} /* */
putchar('\n'); /* */
/* 以下、正規表現の実験部 */
index = styleDel( /* コメント削除関数 */
*desk, /* IN: 作業領域先頭アドレス */
MODE_FOUR ); /* IN: 検索モード(コメント) */
if( INDEX_OK != index ) /* */
{ /* */
printf("コメント削除エラー\n"); /* */
rtnCode = RET_NG; /* */
break; /* */
} /* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
break; /* */
} /* */
/* */
free(*desk); /* 作業領域の解放 */
return ( rtnCode ); /* */
} /* */
/* */
char fileRootin( char** de_desk ) /* ファイル読み込み関数 */
{ /* IN: 作業領域先頭アドレス格納アドレス */
FILE *fin; /* ファイルポインタ */
/* */
char fileName[MAX_F_NAME]; /* ファイル名 */
/* */
char rtnCode = RET_OK; /* リターンコード */
char index = RET_OK; /* 戻り値判定 */
/* */
char spew = 0; /* バッファ吐き出し */
struct stat st; /* for stat() */
/* */
while( 1 ) /* 無限ループ */
{ /* */
printf("検索元ファイル名の入力 > "); /* 画面表示 */
fgets(fileName, MAX_F_NAME, stdin); /* 入力元ファイル名の取得 */
if(!strchr(fileName, '\n')) /* 入力判定 */
{ /* 入力が長すぎる */
while(spew != '\n') /* stdin吐出し */
{ /* */
spew = fgetc(stdin); /* */
} /* */
spew = '\0'; /* */
} /* */
/* */
fileName[strlen(fileName) - 1] = '\0'; /* 末尾改行の処理 */
index = stat(fileName, &st); /* システム情報取得 */
if(INDEX_OK != index) /* 異常処理 */
{ /* */
printf("statまたは入力のエラー\n"); /* 画面表示 */
rtnCode = RET_NG; /* リターンコードにエラー設定 */
break; /* 処理終了 */
} /* */
/* */
*de_desk = (char*)malloc(st.st_size); /* 作業領域の確保 */
if(NULL == de_desk) /* 異常処理 */
{ /* */
printf("mallocでエラー\n"); /* 画面表示 */
rtnCode = RET_NG; /* リターンコードにエラー設定 */
break; /* 処理終了 */
} /* */
/* */
fin = fopen(fileName, "rb"); /* 入力元ファイルオープン(バイナリ) */
if(NULL == fin) /* 異常処理 */
{ /* */
printf("fopenでエラー(入力元)\n"); /* 画面表示 */
rtnCode = FILE_NG; /* リターンコードにファイルエラー設定 */
break; /* 処理終了 */
} /* */
/* */
fread(*de_desk, sizeof(char), st.st_size, fin); /* 作業領域に読み込み */
fclose(fin); /* 入力元ファイルクローズ */
break; /* 処理終了 */
} /* */
/* */
return ( rtnCode ); /* */
}
/* 以下、正規表現の実験部 */
char styleDel( char* desk, unsigned char de_mode )
{
styleSearch(
desk,
de_mode );
return 0;
}
char styleSearch( char* desk, unsigned char de_mode )
{
return 0;
}
*** 修正履歴 [#n2784e26]
ダブルポインタで、
*desk[i]
では参照エラー
(*desk)[i]
が正しい。~
*** 課題 [#g970739e]
+<regex.h>がインクルードできないため、boostの導入が必要か。~
-備考~
ファイルロックは自分で実装してください。