注释转换-小程序

xiaoxiao2021-02-28  102

编写代码时会有多种注释方式,但有的编辑环境不识别其他的注释方式,因此做个小项目来实现将注释方式统一的改为一种。本次注释转换这个小项目就是将所有的C注释全部转换为C++注释。

要实现这个转换就要先理清实际过程中代码都有哪几种状态!所以先来列一个状态转换机来梳理一下什么情况是什么状态。

简单考虑有以下几种状态:

1、无状态:代码的正文部分

2、C状态:注释方式为C注释

3、C++状态:注释方式为C++注释

4、END:结束状态

为了更加清楚直观的了解他们之间的转换关系,用图示的方法来说明一下

首先我们要打开input.c文件,对这个文件内部的文件进行读取,然后处理,否则直接提示用户有错误。 接下来,我们还要打开output.c文件,对处理以后的代码进行写入。

先来说一下转换机制:先创建一个状态机,在读取到文件时将初始状态先设为NULL_STATE,然后通过fputc函数

从文件中按一个字符一个字符的方式来读取,当读到'/*'时,说明接下来读到的是C_STATE状态,然后将状态机的

状态改为C_STATE状态,进入C状态后,接下来就是要判断是否读到'*/',如果读到就将状态机设置为 

NULL_STATE状态。当然在进去C状态后还要考虑其他很多情况,具体在代码中来看。当读到'//'时,则进入

CPP_STATE状态,这时将状态机设置为CPP_STATE状态,CPP注释是按照行来注释的,所以判断CPP状态结束

的标志自然就是'\n'了。在了解了状态机的转换机制之后,接下来就在代码中具体来实现

transform.h

#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> #include <windows.h> #ifndef _TRANSFORM_H_ #define _TRANSFORM_H_ #define _PATHREAD_ "input.c" #define _PATHWRITE_ "output.c" typedef enum STATE { NUL_STATE, //空状态 C_STATE, //C状态 CPP_STATE, //C++状态 END //结束状态 }STATE; void transform(FILE* _read, FILE* _write); //注释状态 void DoCstate(FILE* _read, FILE* _write, STATE *ps);//C状态,结束C状态时要注意注释状态,所以加上结构体指针 void DoCPPstate(FILE* _read, FILE* _write, STATE *ps);//C++状态 void DoNULstate(FILE* _read, FILE* _write, STATE *ps);//结束 #endif //_TRANSFORM_H_ transform.c

#include "transform.h" void transform(FILE* _read, FILE* _write) { STATE state = NUL_STATE; //初始状态设为无状态 while(state != END) { switch(state) { case NUL_STATE: DoNULstate(_read, _write, &state);//因为要改变地址的状态,所以穿过去的是状态的地址 break; case C_STATE: DoCstate(_read, _write, &state); break; case CPP_STATE: DoCPPstate(_read, _write, &state); break; default: break; } } } void DoNULstate(FILE *_read, FILE *_write, STATE *ps) { int first = 0; int second = 0; int third = 0; first = fgetc(_read); switch(first) { case '/': second = fgetc(_read); switch (second) { case '*': { fputc('/',_write);//当读到/*时相当于是C状态,状态改变为C状态 fputc('/',_write);//然后把C注释的标志/*变为C++注释的标志// *ps = C_STATE; } break; case '/': { fputc(first,_write);//遇到//相当于C++状态,不用转换直接把读到的标志写进去 fputc(second,_write); *ps = CPP_STATE;//状态变为C++状态 } break; default: fputc(first,_write); fputc(second,_write); break; } break; case EOF://遇到EOF直接把状态变为结束 fputc(first, _write); *ps = END; break; default: fputc(first, _write);//没有读到注释的标注就直接把读到的写进去 break; } } void DoCstate(FILE *_read, FILE *_write, STATE *ps) { int first = 0; int second = 0; int third = 0; first = fgetc(_read); switch(first) { case '*': { second = fgetc(_read); switch (second) { case '/'://进入C状态后如果读到*/就说明结束了C状态的注释 third = fgetc(_read);//这里只是考虑避免注释到了正文 if(third == '\n') { fputc(third, _write); } else { ungetc(third, _read);//读到非\0时就是*/后面有正文内容,所以回退一下 fputc('\n', _write); } *ps = NUL_STATE; break; case '*': fputc(first, _write); ungetc(second, _read);//遇到两个*,则第一个是正文的* break; default: fputc(first, _write); break; } } break; case '\n'://C注释换行问题 fputc(first,_write); fputc('/',_write); fputc('/',_write); break; case EOF: fputc(first, _write); *ps = END; default: fputc(first,_write); break; } } void DoCPPstate(FILE* _read, FILE* _write, STATE *ps) { int first = 0; int second = 0; first = fgetc(_read); switch(first) { case '\n'://C++状态是按行注释,当一行结束时就把状态变为无状态 { fputc('\n',_write); *ps = NUL_STATE; } break; case EOF: fputc(first, _write); *ps = END; break; default: fputc(first,_write); break; } }

test.c

#include "transform.h" int main() { FILE* fdread; FILE* fdwrite; fdread = fopen(_PATHREAD_,"r"); if(fdread == NULL) { perror("open file for read!\n"); exit(EXIT_FAILURE); } fdwrite = fopen(_PATHWRITE_,"w"); if(fdwrite == NULL) { fclose(fdread); perror("open file for write!\n"); exit(EXIT_FAILURE); } transform(fdread,fdwrite); fclose(fdread); fclose(fdwrite); system("pause"); return 0; }

为了测试项目的效果,采用以下七种方式来测试来判断是否正确

input.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*/

输出的结果为:

output.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;/*xxxx // 4.多行注释问题 // //int i=0; //int j = 0; //int k = 0; // int k = 0; // 5.连续注释问题 // // // 6.连续的**/问题 //* // 7.C++注释问题 // /*xxxxxxxxxxxx*/

转载请注明原文地址: https://www.6miu.com/read-28454.html

最新回复(0)