注释转换_(C风格转为C++风格)

注释转换

思路:
我们先来看一下C风格的注释, 大概有这几种情况

// 1.一般情况
/* 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++风格的注释

我们可以画一个图来帮助理解
这里写图片描述

首先理清楚 5 个状态之间的转换

/* int i = 0; */

这里遇到 / 然后状态变为 “遇到斜杠”, 继续, 遇到星号 * 说明就开始了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 (1)
    {
        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(0);
    }
    FILE *output = fopen("output.c", "w"); //打开output.c 并写入
    if (output == NULL)
    {
        perror("fopen");
        exit(0);
    }


    CommentConvert(input, output);

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

    }

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

    }
    return 0;
}
input.c
// 1.一般情况
/* 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*/
output.c
// 1.一般情况
// 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*/

猜你喜欢

转载自blog.csdn.net/sinat_36629696/article/details/80299405