天天看點

注釋轉換_(C風格轉為C++風格)

注釋轉換

思路:

我們先來看一下C風格的注釋, 大概有這幾種情況

// 1.一般情況
/* int i = 0; */

// 2.換行問題
/* int i = 0; */int j = ;
/* int i = 0; */
int j = ;

// 3.比對問題
/*int i = 0;/*xxxxx*/

// 4.多行注釋問題
/*
int i=0;
int j = 0;
int k = 0;
*/int k = ;

// 5.連續注釋問題
/**//**/

// 6.連續的**/問題
/***/

// 7.C++注釋問題
// /*xxxxxxxxxxxx*/
           

仔細觀察分析, 我們發現這裡面包含五種情況

  • 正常的注釋代碼
  • 遇到了斜杠 /
  • 遇到了星号 *
  • C風格的注釋
  • C++風格的注釋

我們可以畫一個圖來幫助了解

注釋轉換_(C風格轉為C++風格)

首先理清楚 5 個狀态之間的轉換

這裡遇到 / 然後狀态變為 “遇到斜杠”, 繼續, 遇到星号 * 說明就開始了C風格的注釋

狀态轉為 C風格注釋, 然後在遇到星号 *, 進入狀态 “遇到星号”, 再遇到斜杠 /, 說明C風格注釋結束, 回到正常狀态.

然後其他狀态之間的轉換關系可以根據這個圖推理得出

具體實作的代碼

主要用到了 fopen fclose fgetc fputc ungetc 這幾個函數

FILE * fopen(const char * path, const char * mode);
//傳回值:檔案順利打開後,指向該流的檔案指針就會被傳回。
//如果檔案打開失敗則傳回 NULL,并把錯誤代碼存在error中。
//一般而言,打開檔案後會做一些檔案讀取或寫入的動作,若打開檔案失敗
//接下來的讀寫動作也無法順利進行,是以一般在 fopen() 後作錯誤判斷及處理。

//參數 path字元串包含欲打開的檔案路徑及檔案名
//參數 mode 字元串則代表着流形态。
           
int fclose( FILE *fp );
//傳回值:如果流成功關閉,fclose 傳回 0,否則傳回EOF(-1)
//fclose是一個函數名,功能是關閉一個流。
//注意:使用fclose()函數就可以把緩沖區内最後剩餘的資料輸出到核心緩沖區
//并釋放檔案指針和有關的緩沖區。
           
int fgetc(FILE *stream);
//從檔案指針stream指向的檔案中讀取一個字元
//讀取一個位元組後,光标位置後移一個位元組。
//這個函數的傳回值,是傳回所讀取的一個位元組。
//如果讀到檔案末尾或者讀取出錯時傳回EOF(-1)
           
int fputc (int c, FILE *fp);
//将字元ch寫到檔案指針fp所指向的檔案的目前寫指針的位置
//傳回值:在正常調用情況下,函數傳回寫入檔案的字元的ASCII碼值
//出錯時,傳回EOF(-1)。
//當正确寫入一個字元或一個位元組的資料後
//檔案内部寫指針會自動後移一個位元組的位置
           
int ungetc(int c, FILE *stream);
//把一個(或多個)字元退回到steam代表的檔案流中,可以了解成一個“計數器”
//c: 要寫入的字元
//stream: 檔案流指針,必須是輸入流不能是輸出流
//傳回值:字元c - 操作成功,EOF - 操作失敗(int)
           

實作代碼

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>

typedef enum State
{
    NORMAL, //正常的代碼
    MEET_SLASH, //遇到 '/'
    CPP_COMMENT, //C++ 風格注釋
    C_COMMENT, //C 風格注釋
    MEET_ASTERISK, //遇到 '*'
} State;

void CommentConvert(FILE *input, FILE *output)
{
    int ch, nextCh;
    State state = NORMAL;
    while ()
    {
        ch = fgetc(input);
        if (ch != EOF)
        {
            switch (state)
            {
            case NORMAL:
                if (ch == '/')
                {
                    fputc(ch, output);
                    state = MEET_SLASH;
                    //fputc(ch, output);
                }
                else
                {
                    fputc(ch, output);
                    state = NORMAL;
                }
                break;

            case MEET_SLASH:
                if (ch == '/')
                {
                    fputc(ch, output);
                    state = CPP_COMMENT;
                }
                else if (ch == '*')
                {
                    fputc('/', output);
                    state = C_COMMENT;
                    //fputc('/', output);
                }
                else
                {
                    fputc(ch, output);
                    state = NORMAL;
                }
                break;

            case MEET_ASTERISK:
                if (ch == '/')
                {
                    nextCh = fgetc(input);
                    if (nextCh == '\n')
                    {
                        ;
                    }
                    else
                    {
                        fputc('\n', output);
                    }
                    ungetc(nextCh, input);
                    state = NORMAL;
                }
                else if (ch == '*')
                {
                    fputc('*', output);
                    state = MEET_ASTERISK;
                }
                else
                {
                    fputc('*', output);
                    fputc(ch, output);
                    state = C_COMMENT;
                }
                break;

            case CPP_COMMENT:
                if (ch == '\n')
                {
                    //fputc('\r', output);
                    fputc(ch, output);
                    state = NORMAL;
                }
                else
                {
                    fputc(ch, output);
                    state = CPP_COMMENT;
                }
                break;

            case C_COMMENT:

                if (ch == '*')
                {
                    //fputc(ch, output);
                    state = MEET_ASTERISK;

                }
                else
                {
                    //nextCh = fgetc(input);
                    if (ch == '\n')
                    {
                        fputc(ch, output);
                        fputc('/', output);
                        fputc('/', output);

                    }
                    else
                    {
                        fputc(ch, output);
                        //ungetc(nextCh, input);
                    }
                    state = C_COMMENT;

                }

                break;
            }
        }
        else
        {
            break;
        }
    }
}

int main()
{
    FILE *input = fopen("input.c", "r"); //打開input.c 并讀取
    if (input == NULL)
    {
        perror("fopen");
        exit();
    }
    FILE *output = fopen("output.c", "w"); //打開output.c 并寫入
    if (output == NULL)
    {
        perror("fopen");
        exit();
    }


    CommentConvert(input, output);

    if (fclose(output) == -)
    {
        perror("fclose");
        exit();

    }

    if (fclose(input) == -)
    {
        perror("fclose");
        exit();

    }
    return ;
}
           
input.c
// 1.一般情況
/* int i = 0; */

// 2.換行問題
/* int i = 0; */int j = ;
/* int i = 0; */
int j = ;

// 3.比對問題
/*int i = 0;/*xxxxx*/

// 4.多行注釋問題
/*
int i=0;
int j = 0;
int k = 0;
*/int k = ;

// 5.連續注釋問題
/**//**/

// 6.連續的**/問題
/***/

// 7.C++注釋問題
// /*xxxxxxxxxxxx*/
           
output.c
// 1.一般情況
// int i = 0; 

// 2.換行問題
// int i = 0; 
int j = ;
// int i = 0; 
int j = ;

// 3.比對問題
//int i = 0;/*xxxxx

// 4.多行注釋問題
//
//int i=0;
//int j = 0;
//int k = 0;
//
int k = ;

// 5.連續注釋問題
//
//

// 6.連續的**/問題
//*

// 7.C++注釋問題
// /*xxxxxxxxxxxx*/