使用c语言实现注释转换,只要是将c注释转换为c++注释
整体思路
首先,我们需要两个文件,分别存放注释转换前的代码(input.c)和转换后的代码(output.c)
之后,我们对注释转换过程中的出现的几种状态进行分析,得出几种状态之间相互的关系
同时,我们需要对注释转换过程中出现的几种问题进行分析
//1.一般情况
int i = 0
//2.换行问题
/*int i = 0*/
/*int i = 0*/
//3.匹配问题
/*int i = 0;/*xxxxxxx*/
//4.多行注释问题
/*
int i = 0
int j = 9;
*/
//5.连续注释问题
/*int i = 0*//*int j = 9;*/
//6.连续的**/问题
/***/
//7.c++注释问题
// /*xxxxxxxx*/
代码实现
定义各种状态
在这里,我们使用枚举类型来定义各种状态
enum State
{
NUL_STATE, //未知状态
C_STATE, //c注释状态
CPP_STATE, //c++注释状态
END_STATE //结束状态
};
打开文件及关闭文件
int main()
{
//打开文件
FILE *psIn = fopen("input.c", "r");
if (psIn == NULL) //若打开失败,则结束程序
{
exit(EXIT_FAILURE);
}
FILE *psOut = fopen("output.c", "w");
if (psOut == NULL)
{
fclose(psIn); //若input.c打开成功,但output.c打开失败,则需要关闭已经打开的input.c
exit(EXIT_FAILURE);
}
//关闭文件
fclose(psIn);
fclose(psOut);
return 0;
}
状态转换
对不同的状态,我们分别调用不同的函数
void DoCommentConvert(FILE *psin, FILE *psout)
{
enum State state = NUL_STATE; //程序开始时,初始状态为未知状态
while (state != END_STATE)
{
switch (state)
{
case NUL_STATE: //未知状态
NULLState(psin, psout, &state);
break;
case C_STATE: //c注释状态
DoCState(psin, psout, &state);
state = NUL_STATE;
break;
case CPP_STATE: //c++注释状态
DoCppState(psin, psout, &state);
state = NUL_STATE;
break;
case END_STATE: //结束状态
break;
}
}
}
未知状态
通过对取出字的不同进行不同的操作
void NULLState(FILE *psin, FILE *psout, enum State *src)
{
int first = fgetc(psin); //取出一个字
switch (first)
{
case '/': //若为/,则有可能为c或c++注释状态
{
int second = fgetc(psin); //再取出一个字,决定进入某种状态
switch (second)
{
case '*': //c注释状态
fputc('/', psout);
fputc('/', psout);
*src = C_STATE; //将c注释转化为c++注释并且进入c注释状态
break;
case '/': //c++注释状态
fputc('/', psout);
fputc('/', psout);
*src = CPP_STATE; //进入c++注释状态
break;
case EOF: //结束状态
fputc(first, psout); //将first写入文件
*src = END_STATE; //文件结束,进入结束状态
break;
default: //其余情况
fputc(first, psout);
fputc(second, psout); //将first,second写入文件
*src = NUL_STATE; //进入未知状态
break;
}
}
break;
case EOF: //结束状态
*src = END_STATE; //文件结束,进入结束状态
break;
default: //其余情况
fputc(first, psout); //将first写入文件
*src = NUL_STATE; //进入未知状态
break;
}
}
c注释状态
void DoCState(FILE *psin, FILE *psout, enum State *src)
{
while (*src == C_STATE)
{
int first = fgetc(psin); //取出一个字
switch (first)
{
case '*': //有可能c注释结束
{
int second = fgetc(psin);
switch (second)
{
case '/': //c注释结束,进入未知状态
*src = NUL_STATE;
break;
case '*': //出现**的特殊情况
fputc(first, psout);
ungetc(second, psin); //将读到的第二个*退回文件之中
break;
default: //其他情况
fputc(first, psout);
fputc(second, psout);
break;
}
}
break;
case '\n': //出现换行时则略去,以免转换后的c++注释不完整
break;
//注意,c注释中无法直接结束
default: //其他情况
fputc(first, psout);
break;
}
}
}
c++注释状态
void DoCppState(FILE *psin, FILE *psout, enum State *src)
{
while (*src == CPP_STATE)
{
int first = fgetc(psin);
switch (first)
{
case '\n': //c++注释结束
fputc(first, psout);
*src = NUL_STATE; //进入未知状态
break;
case EOF: //文件结束
*src = END_STATE; //进入文件结束状态
break;
default: //其他情况
fputc(first, psout);
break;
}
}
}