*この記事はまだ書きかけです。管理人が今後加筆していく予定ですので、参考にする場合は注意してください。 C言語と正規表現 テストその1 †テキストファイルの内容をメモリ領域にコピーし、正規表現を使って解析する。 制約 †MFC、.NET関数を使用しないこと。 #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; } 修正履歴 †ダブルポインタで、 *desk[i] では参照エラー (*desk)[i] が正しい。 課題 †
|