我们常见的注释转换有两种风格:C语言注释风格和C++注释风格。
C语言注释:/* 注释内容 */
特点:允许多行注释,但不允许嵌套注释
C++注释: //注释内容
特点:允许嵌套注释,但不允许多行注释
这个程序的目的就是为了将C语言的注释转换成C++的注释。我们给定一个”input.c”,程序运行后产生一个对应的”output.c”
这个程序其实内在很复杂,有很多种情况。
如上图所示的七种情况,我们如果用单纯的if…else…来表示,那其中的嵌套情况就太过于复杂。我们考虑用状态机来处理这个问题,分析情况简单描绘如下图。
具体代码如下:
CommentConvert.h
#include<stdlib.h>
typedef enum State
{
NUL_STATE,
C_STATE,
CPP_STATE,
END_STATE,
}State;
void CommentConvert(FILE*pfread, FILE* pfwrite);
void doNulState(FILE* pfread, FILE* pfwrite, State* ps);
void doCState(FILE* pfread, FILE* pfwrite, State* ps);
void doCppState(FILE* pfread, FILE* pfwrite, State* ps);
#endif
CommentConvert.c
#include"CommentConvert.h"
void CommentConvert(FILE*pfread, FILE*pfwrite)
{
State state = NUL_STATE;
while (state != END_STATE) //分成四个状态来简化复杂状态
{
switch (state)
{
case NUL_STATE:
{
doNulState(pfread, pfwrite, &state);
}
break;
case C_STATE:
{
doCState(pfread, pfwrite, &state);
}
break;
case CPP_STATE:
{
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 '*':
{
fputc('/', pfwrite);
fputc('/', pfwrite);
*ps = C_STATE;
}
break;
case '/':
{
fputc('/', pfwrite);
fputc('/', pfwrite);
*ps = CPP_STATE;
}
break;
default:
{
fputc(second, pfwrite);
}
break;
}
}
break;
case EOF:
{
*ps = END_STATE;
}
break;
default:
{
fputc(first, pfwrite);
}
break;
}
}
void doCState(FILE* pfread, FILE* pfwrite, State* ps)
{
int first = fgetc(pfread);
switch (first)
{
case '*':
{
int second = fgetc(pfread);
switch (second)
{
case '/': //C语言注释结束
{
int third = fgetc(pfread);
if (third == '\n')
{
fputc(third, pfwrite);
}
else
{
fputc('\n', pfwrite);
ungetc(third, pfread);
}
*ps = NUL_STATE;
}
break;
case '*':
{
fputc(first, pfwrite);
ungetc(second, pfread);
}
break;
default:
{
fputc(first, pfwrite);
ungetc(second, pfread);
}
break;
}
}
break;
case '\n':
{
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':
{
fputc(first, pfwrite);
*ps = NUL_STATE;
}
break;
case EOF:
{
*ps = END_STATE;
}
break;
default:
{
fputc(first, pfwrite);
}
break;
}
}
运行结果:
运行后在原来的工程目录下新生成了一个output.c文件,我们打开这个文件如下:
可以看到我们已经很好的完成了C注释向C++注释的转换。