注释转换(将C语言注释转化为C++的注释)

c语言中的注释方法为 /* ………*/
c++中的注释方法为 //
要将 input.txt里面的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*/

要将上述所有的c语言注释全部转化为c++注释,上述中,每一种都是一个不同的情况,要是全部都用判断一下,没有总结是很难的。这时,我们就可以运用一种思想:状态机。就是将问题分成几种不同的状态,然后再几个状态之间来回转换。

例如上题中:一共可以分为四种状态:开始状态(无注释状态)、c语言注释状态、c++注释状态、结束状态。
这时候我们就要分析这几种状态之间对应的关系:如下图:
这里写图片描述
这里写图片描述

代码:
头文件
    #ifndef __COMMENT_CONVERT_H__
    #define __COMMENT_CONVERT_H__

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

    typedef enum State   //定义一个枚举,里面是四种状态
    {
        NUL_STATE,   //无注释状态
        C_STATE,     //C语言注释状态
        CPP_STATE,   //C++注释状态
        END_STATE    //结束状态
    }State;

    void DoNulState(FILE *pfRead, FILE *pfWrite, State *ps);  //无注释状态操作
    void DoCState(FILE *pfRead, FILE *pfWrite, State *ps);    //C语言注释状态操作
    void DoCppState(FILE *pfRead, FILE *pfWrite, State *ps);  //C++注释状态操作

    void CommentConvert(FILE *pfRead, FILE *pfWrite); //状态转换

    #endif
源文件
    #include "CommentConvert.h"

    void CommentConvert(FILE *pfRead, FILE *pfWrite)
    {
        enum State state = NUL_STATE;         //开始为无注释状态
        while (state != END_STATE)            //如果不是结束状态,持续循环
        {
            switch (state)
            {
            case NUL_STATE:            //无注释状态
                DoNulState(pfRead, pfWrite, &state);
                break;
            case C_STATE:             //C语言注释状态
                DoCState(pfRead, pfWrite, &state);
                break;
            case CPP_STATE:           //C++注释状态
                DoCppState(pfRead, pfWrite, &state);
                break;
            default:
                break;
            }
        }
    }

    void DoNulState(FILE *pfRead, FILE *pfWrite, State *ps)
    {
        int first = fgetc(pfRead);  //记录第一个字符
        switch(first)          
        {
        case '/':  //表示进入注释状态
            {
                int second = fgetc(pfRead);  //记录第二个字符
                switch (second)
                {
                case '*':        //代码为/* 即将进入C语言代码注释
                    {
                        fputc('/', pfWrite); 
                        fputc('/', pfWrite); //将其转换为C++注释,并打印到output.txt中
                        *ps = C_STATE;  //进入C语言代码注释状态
                    }
                    break;
                case '/':    //代码为// 即将进入C++代码注释状态
                    {
                        fputc('/', pfWrite);
                        fputc('/', pfWrite); // 将C++注释打印到output.txt中
                        *ps = CPP_STATE;  //进入C++注释状态
                    }
                    break;
                default:   //不是C语言的注释,第一个字符只是一个字符'/'
                    {
                        fputc('/', pfWrite); //先将'/'打印
                        fputc(second, pfWrite);  //再将第二个字符打印
                    }
                    break;
                }
            }
            break;
        case EOF: //表示已经结束
            {
                fputc(first, pfWrite);
                *ps = END_STATE; //进入结束状态
            }
            break;
        default:
            {
                fputc(first, pfWrite); //表示第一个就是字符,将其打印
            }
            break;
        }
    }

    void DoCState(FILE *pfRead, FILE *pfWrite, State *ps)
    {
        int first = fgetc(pfRead); //读取字符进行判断
        switch (first)
        {
        case '*':  //表示C语言注释可能会结束
            {
            int second = fgetc(pfRead); //读取第二个字符
            switch (second) 
            {
            case '/': //遇见*/ 表示C语言注释结束
                {
                int third = fgetc(pfRead); // 读取第三个字符,判断是否换行(上述中的第二种情况)
                if (third != '\n')  //不是换行符
                {
                    fputc('\n', pfWrite);  //要将其换行
                    ungetc(third, pfRead); //因为我们已经把该字符取出来了,接下来就不容易判断,所以还要讲该字符退回流中
                }
                else
                {
                    fputc(third, pfWrite); //如果是换行符,直接但因就可以
                }
                *ps = NUL_STATE;  //状态转换为无注释状态
                }
                break;
            default:
                {
                fputc(first, pfWrite); //第二个字符不是'/',表示第一个 * 只是一个字符'*'
                ungetc(second, pfRead); //同上面一样,为了不影响下面的判断,要将该字符退回流中
                }
                break;
            }
            }
            break;
        case '\n': //如果是换行符,就将其打印,但要加上两个/,因为C语言的注释是在每一行的开始
            {
            fputc(first, pfWrite);
            fputc('/', pfWrite);
            fputc('/', pfWrite);
            }
            break;
        default :
            {
            fputc(first, pfWrite); //不是*,表示只是一个字符,将其打印
            }
            break;
        }
    }

    void DoCppState(FILE *pfRead, FILE *pfWrite, State *ps)
    {
        int first = fgetc(pfRead); //读取第一个字符
        switch (first)
        {
        case '\n':  //如果是'\n',将其打印即可,并回到无注释状态
            {
            fputc(first, pfWrite);
            *ps = NUL_STATE;
            }
            break;
        case EOF:  //  表示结束,直接到结束状态
            {
            fputc(first, pfWrite);
            *ps = END_STATE;
            }
            break;
        default:
            {
                fputc(first, pfWrite); //表示只是一个字符,将其打印
            }
            break;
        }
    }

注:ungetc()表示把一个(或多个)字符退回到steam代表的文件流中

主函数(测试代码)
    #define _CRT_SECURE_NO_WARNINGS 1

    #include "CommentConvert.h"

    void test()
    {
        FILE *pfRead = NULL;
        FILE *pfWrite = NULL;
        pfRead = fopen("input.txt", "r");
        if (pfRead == NULL)
        {
            perror("open file for read");
            system("pause");
            exit(EXIT_FAILURE);
        }
        pfWrite = fopen("output.txt", "w");
        if (pfWrite == NULL)
        {
            perror("open file for write");
            system("pause");
            exit(EXIT_FAILURE);
        }
        CommentConvert(pfRead, pfWrite);
        fclose(pfRead);
        pfRead = NULL;
        fclose(pfWrite);
        pfWrite = NULL;
    }

    int main()
    {
        test();
        system("pause");
        return 0;
    }
结果:

这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值