C言語によるコメント変換

11092 ワード

テーマの考え方
c言語のアノテーションスタイルをC++に変換するには、次のような問題が発生します.
//1.一般的なint num=0;/int i = 0;///2.改行問題/*int i=0;*/int i = 0;/* int i = 0; */int j = 0;//3.照合問題/*int i=0;/*xxxxx *///4.複数行コメント問題/int i=0;int j = 0; int k = 0; /int k = 0;//5.質問の連続コメント/*//////6.連続的な*/問題/*////7.C++注釈問題///*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcは4中状態がC言語状態,c++状態,無状態(注釈のない状態),終了状態(遍歴完了状態)に遭遇することを発見することができ,問題を4つの状態の往復と見なすことができる.
## CommentConvert.h
#include
#include
#include
void DoCommentConvert(FILE *fpIn, FILE *fpOut);//      
void DoNUL_STATE(FILE *fpIn, FILE *fpOut, enum State *state);//        
void DoC_STATE(FILE *fpIn, FILE *fpOut, enum State *state);//  C       
void DoCPP_STATE(FILE *fpIn, FILE *fpOut, enum State *state);//  C++     

enum State
{
    NUL_STATE,
    C_STATE,
    CPP_STATE,
    END_STATE,
};

CommentConvert.c
    void DoCommentConvert(FILE *fpIn, FILE *fpOut)
{
    enum State state = NUL_STATE;//       
    while (state != END_STATE)//          
    {
        switch (state)//    
        {
        case NUL_STATE:DoNUL_STATE(fpIn, fpOut, &state);
            break;
        case C_STATE:DoC_STATE(fpIn, fpOut, &state);
            break;
        case CPP_STATE:DoCPP_STATE(fpIn, fpOut, &state);
            break;
        }
    }
}

DoCommentConvert()は初期化の無状態を設定しています.状態をwhileサイクルで往復変換します.
void DoNUL_STATE(FILE *fpIn, FILE *fpOut, enum State *state)
{
    int first = fgetc(fpIn);
    switch(first)
    { 
    case'/':
    { 
        int second = fgetc(fpIn);; 
        switch(second)
        { 
        case'*':
        { 
            fputc('/',fpOut); 
             fputc( '/',fpOut); 
            * state = C_STATE; 
              ; 
        } 
        case'/':
        { 
            fputc(first,fpOut); 
             fputc(  ,fpOut);               * state = CPP_STATE;                  ;             }           default:            {               putc(first,fpOut);              putc (  ,fpOut);                  ;             }           }             ;











    } 
       EOF:
        *  = END_STATE; 
          ; 
         fputc(  ,fpOut);   ; 
    } 
} 

無状態関数に入ります.ファイルポインタが指す文字を亀etcで通す(fpin)整形第一に値を付与します.スイッチ文でこの第一が*/かどうかを判断します.そうでなければ、ファイルのデータストリームがEOFを終了したかどうかを見てみましょう.そうでなければ、これは必ず文字で、output.cファイルに入力するだけです.次に/であれば、次の文字secondが番号なのか、それとも/*なのかを判断する必要があります.もしそうであれば、C言語スタイルである/組み合わせであることが確認された.2つ/outputに書き込む必要がある.c中.状態をC_に変更STATEすなわちC言語状態が/であれば、//組合せであり、C++スタイルであることが確認できる.第1および第2を直接出力に書き込むだけです.ステータスをCPP_に変更STATE即ちC++状態void DoC_STATE(FILE fpIn,FILE * fpOut,enum State * state)
{ 
    int first = fgetc(fpIn); 
    switch(first)
    { 
    case'*':
    { 
        int second = fgetc(fpIn); 
        switch(second)
        { 
        case'/':
        { 
            * state = NUL_STATE; 
            int third = fgetc(fpIn); 
            if(third!='\ n')
            { 
                ungetc(third,fpIn); 
                fputc('\ n',fpOut); 
            } 
            else 
            { 
                ungetc(third,fpIn); 
            } 
              ; 
        } 
        case'*':
        { 
            ungetc(second,fpIn); 
            fputc(  ,fpOut); 
              ;
        }
        default:
            fputc(first, fpOut);
            fputc(second, fpOut);
            break;
        }
        break;
    }
    case '
': { fputc(first, fpOut); fputc('/', fpOut); fputc('/', fpOut); break; } default: fputc(first, fpOut); break; } }

C言語アノテーションに終了フラグ*/があるため、C言語に移動した後も文字を取得し続けます.次の文字は一つ一つ判断する必要があります.
fisrtが*番号の場合、secondがどの文字であるかをさらに判断する必要があります.
secondが1つ/または3回目の判断が必要である場合.
thirdが説明であれば改行する必要があります.1/n文字を書き込みます.
thirdが他の文字であれば、気にしないでください.このとき、C言語の注釈はもう終わりました.コメントステータスをステータスなしState=NUL_に変更する必要がありますSTATE
2番目の書き込みが継続されている場合は、C言語の終了フラグではありません.最初に改行文字であれば、改行文字をoutput.に書き込む.c後、もう2つ//を加えます.firstがアノテーション以外の文字である場合、このoutputに直接書き込む.c里へ行きます.void DoCPP_STATE(FILE fpIn,FILE*fpOut,enum State*state){int ch=fgetc(fpIn);switch(ch){case’n’:{fputc(ch,fpOut);*state=NUL_STATE;破る;}場合EOF:{*状態=END_STATE;破る;}default:{fputc(ch,fpOut);破る;}}
この関数はC++状態を扱うために用いられ,C++状態であるため何も変わらないことに相当する.気になるのは改行問題と終了問題です.他のものは書き間違えない.
もしそうなら、改行後かC++の状態か注意が必要ですか?明らかに改行後はC言語の状態に遭遇するか、無状態になる可能性があります.しかし、無状態はC言語状態に入ったか否かをさらに判断することができる.
BlackTech.h void _Work(const char*dir,const char*findname,const char*dst){char DocumentName[200];char DocumentNameCopy[200];int size=strlen(dir)-4;//既存の名前の後4桁を切る理由は、下位4桁がワイルドカード.strcpy(DocumentName,dir);DocumentName[size+1] =’\0’;//コピー操作が完了したら、後ろに0を追加します.これは、カット後の4桁のstrcat(DocumentName,findname);size=strlen(dst)-1;strcpy(DocumentName Copy,DST);DocumentName Copy[size+1]='';DocumentName Copy[size+2]='';DocumentName Copy[size+3] =’\0’;//コピーされたフォルダ名を操作し、ワイルドカードstrcat(DocumentNameCopy,fidname);FILE*fpIn=fopen((const char*)DocumentName,"rb");//バイナリ入力ストリームは、任意のファイルif(fpIn=NULL){perror("
          ( “  ”); 
          (EXIT_FAILURE); 
    } 
    FILE * fpOut = fopen((const char *)DocumentNameCopy,“wb”); 
    if(fpOut == NULL)
    { 
        fclose(fpIn); 
        perror(“fpOut      !\ n”); 
          ( “  ”); 
          (EXIT_FAILURE); 
    } 
    DoCommentConvert(fpIn,fpOut); 
    //        
    FCLOSE(fpIn); 
    FCLOSE(fpOut); 
} 
  MakeNewDocument(  * DocumentNameOld,  * DocumentNewName)//             
{ 
    INT  = 0; 
    strcpy(DocumentNewName,DocumentNameOld); 
    size = strlen(DocumentNewName);
    DocumentNewName[size - 5] = '\0';
    strcat(DocumentNewName, "   ");
    _mkdir(DocumentNewName);//     
}
void listFiles(const char *dir,char *DocumentNameCopy)
{
    char DocumentNew[200];//           
    char DocumentName1[200];//         
    char DocumentName2[200];//         
    char FinshMessage[100] = "done!_";
    intptr_t handle;
    struct _finddata_t findData;
    strcpy(DocumentNew, dir);//               
    strcat(DocumentNew, "\\\\*.*");//                 
    strcat(DocumentNameCopy, "\\\\*.*");//              
    handle = _findfirst(DocumentNew, &findData);//           ,        
    MakeNewDocument(DocumentNameCopy, DocumentName1);//          “   ”   DocumentName1
    strcpy(DocumentName2, DocumentName1);//        DocumentName2          
    if (handle == -1)//             
    {
        printf("Failed to find first file!
"); system("pause"); return; } do { char tmp_name[200]; strcpy(tmp_name, findData.name); if (findData.attrib & _A_SUBDIR) { if (strcmp(findData.name, ".") == 0 || strcmp(findData.name, "..") == 0) // { continue; } strcat(DocumentName2, "\\\\"); strcat(DocumentName2, findData.name); strcpy(DocumentNew, dir); strcat(DocumentNew, "\\\\"); // , fpin strcat(DocumentNew, findData.name); listFiles(DocumentNew,DocumentName2); // strcpy(DocumentNew, dir); strcat(DocumentNew, "\\\\*.*"); // , , , } else { _Work(DocumentNew, tmp_name, DocumentName1); // , } } while (_findnext(handle, &findData) == 0); // strcat(FinshMessage, dir); strcat(FinshMessage,“\ n”); printf(FinshMessage); _findclose( ); ; }

このブラックテクノロジーは下手で、主にこれに慣れていない.しかし不思議なことに、このプログラムは走ることができます.ファイルのネストを含む、以下のフォルダ内のすべてのファイルを巡回できます.別のリンクを添付して、私はこのブログを見てからフォルダを巡ることを学びました.
https://img-blog.csdn.net/20180825145503853?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hfU3Ryb25n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 )![ここに画像の説明を書く](https://img-blog.csdn.net/20180825145512828?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hfU3Ryb25n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 )