FrontPage

*この記事はまだ書きかけです。管理人が今後加筆していく予定ですので、参考にする場合は注意してください。

C言語と正規表現 テストその1

テキストファイルの内容をメモリ領域にコピーし、正規表現を使って解析する。
解析の題材として、C/C++言語ソースファイルを扱う。

制約

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;
}

修正履歴

ダブルポインタで、

*desk[i]

では参照エラー

(*desk)[i]

が正しい。

課題

  1. <regex.h>がインクルードできないため、boostの導入が必要か。
  • 備考
    ファイルロックは自分で実装してください。

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-02-08 (月) 02:08:12 (5191d)