C/C++的注释转换

来源:互联网 发布:我的世界天堂门js 编辑:程序博客网 时间:2024/05/09 20:29

C/C++的注释风格有两种,一种是“/*xxxxxxx*/ ”,这种注释可以注释行也可注释段

   第二种是“//”,这种注释只能注释行

目标要实现将所有/* xx*/注释风格变成//注释风格

思路:使用有限状态机编程

可能会出现的情况

// 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种状态,C状态(为/**/风格),CPP状态(//),无状态(NULL),结束状态(END)

根据不同情况进入不同状态。如图


代码实现:

1.头文件部分

#ifndef __COMMENTC_H__#define __COMMENTC_H__#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>#include <stdlib.h>typedef enum Option{END_STATE,NULL_STATE,C_STATE,CPP_STATE,}OP;void CommentChange(FILE *pin,FILE *pout);void Normal_Change(FILE *pin,FILE *pout,OP *state);void C_Change(FILE *pin,FILE *pout,OP *state);void Cpp_Change(FILE *pin,FILE *pout,OP *state);#endif
2.测试部分:

#include "zhushi.h"void test(){FILE *pin = NULL;FILE *pout = NULL;pin = fopen("input.txt","r");if(NULL == pin){perror("open file for read");exit(1);}pout = fopen("output.txt","w");if(NULL == pout){perror("open file for write");fclose(pin);//此时pin已经被打开,结束前关闭。exit(1);}CommentChange(pin,pout);}int main(){test();return 0;}

3.函数实现部分

#include "zhushi.h"void CommentChange(FILE *pin,FILE *pout){OP state = NULL_STATE;//先将状态置为无状态while(state){switch(state){case NULL_STATE:Normal_Change(pin,pout,&state);break;case C_STATE:C_Change(pin,pout,&state);break;case CPP_STATE:Cpp_Change(pin,pout,&state);break;case END_STATE:break;default:break;}}printf("转换注释完成,文件已保存在output.txt\n");fclose(pin);fclose(pout);}void Normal_Change(FILE *pin,FILE *pout,OP *state){int first = 0;int second = 0;first = fgetc(pin);//从pin指向的文件拿出一个字符,返回值为intswitch(first)//判断拿出的第一个字符,根据不同的字符进入不同情况{case'/':fputc(first,pout);//先把/放入pout所指向的文件中,之后的再做判断second = fgetc(pin);switch(second){case'*':fputc('/',pout);//将 /* 转换成 // 然后进入C状态*state = C_STATE;break;case'/':fputc(second,pout);//进入 CPP状态*state = CPP_STATE;break;default:break;}break;case EOF:fputc(first,pout);//直接将结束符号输入到目标文件中*state = END_STATE;break;default:fputc(first,pout);break;}}void C_Change(FILE *pin,FILE *pout,OP *state){int first = 0;int second = 0;int third = 0;first = fgetc(pin);switch(first){case '*':second = fgetc(pin);switch(second){case '/'://如果是*/则判断换行third = fgetc(pin);if('\n' == third){fputc(third,pout);}else{ungetc(third,pin);//如果不是换行符则清空缓冲区,退回一个字符并换行fputc('\n',pout);}*state = NULL_STATE;break;case '*'://如果是**/则需要写入第一个*,并将第二个*用ungetc释放,不然会漏判fputc(first,pout);ungetc(second,pin);break;default:fputc(first,pout);ungetc(second,pin);//释放second,否则*a的情况会漏掉a的判定。break;}break;case '/'://注释符号 匹配问题 /*int i = 0;/*xxxxx*/  此时中间有/*则不输出,之后按照C状态走second = fgetc(pin);switch(second){case '*':*state = C_STATE;break;default:fputc(first,pout);fputc(second,pout);break;}break;case '\n'://多行注释问题,如果first是\n则 下一行开头注释//fputc(first,pout);fputc('/',pout);fputc('/',pout);break;//先跳出。此时还是C状态,知道遇到*/后跳出C状态。case EOF:fputc(first,pout);*state = END_STATE;default:fputc(first,pout);break;}}void Cpp_Change(FILE *pin,FILE *pout,OP *state){int first = 0;first = fgetc(pin);switch(first){case '\n':fputc(first,pout);*state = NULL_STATE;break;case '/':                                //处理这类嵌套的情况// /*xxxxxxxxxxxx*/    {          int second = fgetc(pin);          if (second == '*')          {              *state = C_STATE;          }          else          {              fputc(first, pout);              fputc(second, pout);          }          break;      }case EOF:fputc(first,pout);*state = END_STATE;break;default:fputc(first,pout);break;}}
结果展示:



完。

原创粉丝点击