【18.8.7】C语言注释向C++注释的转化

版权声明:Oce2ns的大板 https://blog.csdn.net/weixin_39392653/article/details/81490640

C语言注释对比C++注释,功能要明显差一些,因此,当程序中需要将C语言的注释转化时,就需要一个注释的转化软件。毕竟对于大量的代码,我们不可能一个一个的去更改。

在编程初期,我们应该想到,对于C注释开始的识别,但会牵扯的/是除号。或者别的用途,包括结束时,*号的识别。做一个简单的情况分析后,总结出,将其各种情况,用一个状态机去解决。这样可以将无限种的可能,转化为有限种的情况。文本状态,C语言注释的状态,C++注释的状态,和结束文本的标志(EOF)。

文本状态

遇到了‘/*’就开始进入了C语言的注释状态

遇到了‘//’就开始的C++的注释状态

遇到了‘EOF’代表我的文本已经读取结束

C语言注释状态

遇到‘*/’结束,进入文本状态

C语言不支持嵌套注释,所以里面也不会进入C++注释状态

C语言注释在文本结束前一定会‘*/’结束,不会再结束注释前就EOF退出

C++注释状态

当着一行注释结束时,C语言注释就结束,也就是遇到‘/n’结束

当注释中找到EOF文件结束标志,证明这行就是最后一行,直接结束

同理,在C++注释中也不会跳到C语言的注释

结束标志EOF

结束都结束了,也就不谈转入别的状态了好吧

这里写图片描述

解决完这个就是开始码代码。同样使用多个.c文件,将代码拆开写。这样问题比较容易找出。先是测试的test.c文件。

test.c

#include"Annotation.h"//印一下.h的头文件
void test()
{
    FILE * pread = NULL;
    FILE * pwrite = NULL;
    pread = fopen("HeadsomeYZX.txt","r");//从流中读取文本内容,这里的。txt文件名是乱起的,就是输入文件,就是已经有的文本
    if(pread == NULL)
    {
        printf("Error opening read");//解决读取失败。
        exit(EXIT_FAILURE);
    }
    pwrite = fopen("SomelyMYT.txt","w");//从流中写一个文件
    if(pwrite == NULL)
    {
        printf("Error opening write");
        exit(EXIT_FAILURE);
    }
    AnnCtoCPP(pread,pwrite);//核心的转换功能,将他写到核心.c文件中
    fclose(pread);//结束流
    pread = NULL;//指针指向空
    fclose(pwrite);
    pwrite = NULL;
}

int main()
{
    test();
    return 0;
}

Annotation.c

核心文件

#include"Annotation.h" 
void AnnCtoCPP(FILE *pread,FILE *pwrite)
 {
     State state = text_state;//初始化状态,初始化为文本状态
     while(state != end_state)//只有读取到文字并非结束状态时进入状态选择
     {
         switch(state)
         {
         case c_state:
             Annotationc_cPP(pread,pwrite,&state);//进入c注释转化为c++注释状态
             break;
         case text_state:
             Annotationtext_cPP(pread,pwrite,&state);//进入文本状态
             break;
         case cPP_state:
             NOTAnnotation(pread,pwrite,&state);//进入C++注释状态
             break;
         }
     }
 }
 void Annotationc_cPP(FILE *pread,FILE *pwrite,State *p)
 {
     int first = fgetc(pread);//先读一个字符
     switch(first)
     {
     case '*'://读到*,开始敏感,因为可能是遇到了C注释的结束
         {
             int second = fgetc(pread);
             switch(second)
             {
             case '/'://cPP注释结束。
                 {
                     int third = fgetc(pread);//判断后面还有没有内容
                     if(third == '\n')//后面无内容
                     {
                         fputc(third,pwrite);
                     }
                     else
                     {
                         fputc('\n',pwrite);//注释结束了,但是后面有内容,将其换行打印
                         ungetc(third,pread);
                     }
                     *p = text_state;
                 }
                 break;
             case '*'://这是一个特殊状态,即/***/读到*,后下一个不是/,继续读,可能错过*/的结束标志
                 {
                     fputc(first,pwrite);
                     ungetc(second,pread);//将其返回文本中,下一次继续从这里读
                 }
                 break;
             default :
                 {
                     fputc(first,pwrite);
                     ungetc(second,pread);
                 }
                 break;
             }
         }
         break;
     case '\n'://在C语言的注释中如果遇到\n就换行,在输出两个/
         {
             fputc(first,pwrite);
             fputc('/',pwrite);
             fputc('/',pwrite);
         }
         break;
     default ://后面什么都不是就代表,这个*不是注释的结束
         {
             fputc(first,pwrite);
         }
         break;
     }
  }
 void Annotationtext_cPP(FILE *pread,FILE *pwrite,State *p)
 {
     int first = fgetc(pread);
     switch(first)
     {
     case '/'://文本状态读取到/开始敏感,可能进入注释状态
         {
             int second = fgetc(pread);
             switch(second)
             {
             case '*'://遇到*进入C语言注释状态,把他转化成//的C++注释状态
                 {
                     fputc('/',pwrite);
                     fputc('/',pwrite);
                     *p = c_state;//进入C语言注释状态,去寻找注释结束标志
                 }
                 break;
             case '/'://遇到/进入C++注释状态
                 {
                     fputc('/',pwrite);
                     fputc('/',pwrite);
                     *p = cPP_state;
                 }
                 break;
             default ://后面不是代表/只是别的功能
                 {
                     fputc(first,pwrite);
                     fputc(second,pwrite);
                 }
                 break;
             }
         }
         break;
     case EOF://文本遇到EOF,结束文本
         {
             fputc(first,pwrite);
             *p = end_state;
         }
         break;
     default ://正常打印文本
         fputc(first,pwrite);
         break;
     }
 }
 void NOTAnnotation(FILE *pread,FILE *pwrite,State *p)
 {
     int first = fgetc(pread);
     switch(first)
     {
     case '\n'://C++注释换行就意味着结束注释
         {
             fputc(first,pwrite);
             *p = text_state;
         }
         break;
     case EOF://遇到EOF结束文件
         *p = end_state;
         break;
     default :
         fputc(first,pwrite);
         break;
     }
 }

Annotation.h

头文件

#ifndef __AnnotationCtoCPP_H__
#define __AnnotationCtoCPP_H__
#include <stdio.h>
#include <stdlib.h>
typedef enum //使用枚举,状态机
{
    text_state,
    c_state,
    cPP_state,
    end_state
}State;//重命名,这样后面写代码,可以少写一些
void AnnCtoCPP(FILE *pread,FILE *pwrite);
void Annotationc_cPP(FILE *pread,FILE *pwrite,State *pstate);
void Annotationtext_cPP(FILE *pread,FILE *pwrite,State *pstate);
void NOTAnnotation(FILE *pread,FILE *pwrite,State *pstate);


#endif

测试一下功能

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

例子貌似不够刁钻啊。那来个刁钻测试用例

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

猜你喜欢

转载自blog.csdn.net/weixin_39392653/article/details/81490640