注释转换(c->c++)小项目

程序新思路
注释转换一开始去想的时候,会觉得很复杂。因为在一个源文件里出现注释的情况虽然不会太多,但是可能会出现各种各样,形形色色的注释,在转换程度上去想的时候会觉得很复杂,不同的问题都要有不同的解决方法的。

在这里简单的罗列注释转换可能出现的几种情况:

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

// 2.换行问题
/* int i = 0; */int j = 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++注释问题
// /*xxxxxxxxxxxx*/

在注释转换的时候肯定不仅仅只有这些问题,可能有些也没有想到位。所以我们会发现要处理的情况会很多,如果一个一个问题挨个解决的话,代码就会有复杂性。我们可以这样去给一个思路:
这里写图片描述

图中:注释转换过程使用了有限状态机,可以给我们提供一个新的思路。把注释转换切换到4中状态中,根据有限的条件进入相应的状态下去处理,并在根据条件进入下一个状态,依次循环,直到遇到eof结束。
有限状态机(finite state machine)是一个数学概念,如果把它运用于程序中,可以发挥很大的作用。它是一种协议,用于有限数量的子程序(“状态”)的发展变化。每个子程序进行一些处理并选择下一种状态(通常取决于下一段输入)。有限状态机(FSM)可以用作程序的控制结构。

程序代码:
头文件AnnotationConversion.h

#ifndef __ANNOTATIONCONVERSION_H__
#include<stdio.h>
#include<windows.h>
#define CHMOD "input.c"
#define FINAL "output.c"
typedef enum STATE  //枚举定义四种状态
{
    NULL_STATE,
    C_STATE,
    CPP_STATE,
    EOF_STATE,
}STATE;

void Execute(FILE* pfin, FILE* pfout);//转换函数
void DoNULLConvert(FILE* pfin, FILE* pfout,STATE *state);//普通状态
void DoCConvert(FILE* pfin, FILE* pfout, STATE *state);//C状态函数
void DoCPPConvert(FILE* pfin, FILE* pfout, STATE *state);//C++状态函数


#endif//__ANNOTATIONCONVERSION_H__

实现部分AnnotationConversion.c

#include "AnnotationConversion.h"


void Execute(FILE* pfin, FILE* pfout)//转换函数
{
    STATE state = NULL_STATE;        //定义初始状态为普通状态
    while (state != EOF_STATE)
    {
        switch (state)
        {
        case NULL_STATE:
            DoNULLConvert(pfin, pfout, &state);
            break;
        case C_STATE:
            DoCConvert(pfin, pfout, &state);
            break;
        case CPP_STATE:
            DoCPPConvert(pfin, pfout, &state);
            break;
        default:
            break;
        }
    }
}



void DoNULLConvert(FILE* pfin, FILE* pfout, STATE *state)//普通状态操作函数
{
    int first = fgetc(pfin);
    switch (first)
    {
        case '/':
            //普通状态遇到/后,紧接着判断下一个字符。
        {
            int second = fgetc(pfin);
            switch (second)
            {
                case '/':
                    //遇到//依然输出//并进入c++注释状态
                {
                    fputc(first, pfout);
                    fputc(second, pfout);
                    *state = CPP_STATE;
                }
                    break;
                case '*': 
                    //遇到/*依然输出//并进入c注释状态
                {
                    fputc(first, pfout);
                    fputc('/', pfout);
                    *state = C_STATE;
                }
                    break;
                default://正常语句:(例如/hehe/),直接写进文件。
                {
                    fputc(first, pfout);
                    fputc(second, pfout);
                }
                    break;
                }
        }
            break;
        case EOF:
            //结束标志
        {
            *state = EOF_STATE;
        }
            break;
        default:
            //正常语句
        {
            fputc(first, pfout);
        }
            break;
    }

}


void DoCConvert(FILE* pfin, FILE* pfout, STATE *state)//c注释状态操作函数
{
    int first = fgetc(pfin);
    switch (first)
    {
    case '*':
        //遇到*,同样紧接着判断下一下个字符
    {
        int second = fgetc(pfin);
        switch (second)
        {
        case '/':
            //如果是/,表示注释结束,直接回到空状态
        {
            *state = NULL_STATE;
            int third = fgetc(pfin);
            //获取第三个字符是因为可能出现(/*hehe*/int i = 0;)这种情况
            if ('\n' == third)
            {
                fputc(third, pfout);
            }
            else
            {
                fputc('\n', pfout);
                ungetc(third, pfin);
            }

        }
            break;
        default:
            //针对/***/情况
            fputc(first, pfout);
            ungetc(second, pfin);
            break;
        }
    }
            break;
    case '\n':
        //针对多行C语言注释问题
    {
        fputc(first, pfout);
        fputc('/', pfout);
        fputc('/', pfout);
    }
        break;
    default:
        fputc(first, pfout);
        break;
    }
}


void DoCPPConvert(FILE* pfin, FILE* pfout, STATE *state)//C++注释转换操作函数
{
    int first = fgetc(pfin);
    switch (first)
    {
        case '\n':
        {
            fputc(first,pfout);
            *state = NULL_STATE;
        }
            break;
        case EOF:
            *state = EOF_STATE;
            break;
        default:
            fputc(first, pfout);
            break;
    }
}

测试部分test.c
针对fopen、fread、fwrite三个函数在我之前写的文件流通讯录中有详细解释http://blog.csdn.net/quinn0918/article/details/72526886

#include "AnnotationConversion.h"
#pragma warning (disable:4996)
int main()
{
    FILE* pfread = fopen(CHMOD, "r");
    if (pfread == NULL)
    {
        perror("out of for read");
        exit(1);
    }
    FILE* pfwrite = fopen(FINAL, "w");
    if (pfwrite == NULL)
    {
        fclose(pfread);
        perror("out of for write");
        exit(1);
    }
    Execute(pfread, pfwrite);
    printf("转换成功\n");
    fclose(pfread);
    fclose(pfwrite);
    system("pause");
    return 0;
}

针对前面一开始提出的问题,程序运行注释转换后结果为:

这里写图片描述
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值