假如现在有一个.c的文件,它里面有C语言的注释(/…/),C++的注释(//),当然也有正常的代码了,现在我们想要把里面的注释统一一下,将C语言注释全部转换为C++的注释,该怎么做呢?
思路:
我们可以这么想,它里面无非有四种类型:
1.正常代码
2.C注释
3.C++注释
4.文件结束标志EOF
我们要向把C注释全部转化成C++注释,当然要分析一下这四种类型之间的过渡关系了,图解如下:
经过我们分析,如上图,
1.正常代码遇到/*之后会变成C注释,遇到//之后会变成C++代码,而遇到EOF会结束;
2.C代码遇到**/会变成正常代码,不可能会遇到EOF;
3.C++代码遇到‘\n’会变成正常代码,遇到EOF会就会结束
例如:
测试用例如下:
// 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*/
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"CommentConvert.h"
void test()
{
FILE *pfread = NULL;//从哪里读入
FILE *pfwrite = NULL;//改完之后写到哪里
pfread = fopen("input.c", "r");
if (pfread == NULL)
{
perror("open file for read");
}
pfwrite = fopen("output.c", "w");
if (pfwrite == NULL)
{
perror("open file for write");
}
CommentCovert(pfread, pfwrite);//注释转化
fclose(pfread);
pfread = NULL;
fclose(pfwrite);
pfwrite = NULL;
}
int main()
{
test();
return 0;
}
CommentConvert.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"CommentConvert.h"
void DoNulState(FILE *pfread, FILE *pfwrite, State *ps)
{//正常代码函数
char first = fgetc(pfread);
switch (first)
{
case'/':
{
char second = fgetc(pfread);
switch (second)
{
case'*'://遇到/*改成// {
fputc('/', pfwrite);
fputc('/', pfwrite);
*ps = C_STATE;//再将状态置为C语言注释代码
}
break;
case'/':
{
fputc(first, pfwrite);
fputc(second, pfwrite);
*ps = CPP_STATE;//遇到//原样输出,再将状态置为C++代码
}
break;
case EOF:
{
fputc(first, pfwrite);
*ps = END_STATE;//遇到EOF停止
}
default:
fputc(first, pfwrite);//其他情况照常输出
fputc(second, pfwrite);
break;
}
}
break;
case EOF:
*ps = END_STATE;
break;
default:
fputc(first, pfwrite);
*ps = NUL_STATE;
break;
}
}
void DoCState(FILE *pfread, FILE *pfwrite, State *ps)
{
char first = fgetc(pfread);
switch (first)
{
case'*':
{
char second = fgetc(pfread);
switch (second)
{
case'/'://C代码里面遇到*/还应考虑下一个字符是什么
{
char third = fgetc(pfread);
if (third != '\n')//如果不是换行,先换行
{
fputc('\n', pfwrite);
ungetc(third, pfread);
}
else
{
fputc(third, pfwrite);//是换行符,把third还回去
}
*ps = NUL_STATE;//状态置为正常代码
}
break;
case'*':
{
fputc(first, pfwrite);
ungetc(second, pfread);//如果c代码后遇到两个*,将第一个*输出,再将第二个还回去,继续判断
*ps = C_STATE;
}
break;
default:
{
fputc(first, pfwrite);
fputc(second, pfwrite);
}
break;
}
}
break;
case'\n':
{//C代码遇到换行,说明是多行注释
fputc('\n', pfwrite);//先换行
fputc('/', pfwrite);//再转化注释
fputc('/', pfwrite);
*ps = C_STATE;
}
break;
default:
fputc(first, pfwrite);
break;
}
}
void DoCppState(FILE *pfread, FILE *pfwrite, State *ps)
{
char first = fgetc(pfread);
switch (first)
{
case'\n'://遇到换行变为正常代码
fputc(first, pfwrite);
*ps = NUL_STATE;
break;
case EOF://遇到EOF结束
*ps = END_STATE;
break;
default:
fputc(first, pfwrite);
break;
}
}
void CommentCovert(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;
case END_STATE:
break;
}
}
}
CommentConvert.h
#ifndef __CommentConvert_H__
#define __CommentConvert_H__
#include<stdio.h>
#include<stdlib.h>
typedef enum State
{
NUL_STATE,
C_STATE,
CPP_STATE,
END_STATE
}State;
void DoNulState(FILE *pfread, FILE *pfwrite, State *ps);
void DoCState(FILE *pfread, FILE *pfwrite, State *ps);
void DoCppState(FILE *pfread, FILE *pfwrite, State *ps);
void CommentCovert(FILE *pfread, FILE *pfwrite);
#endif // __CommentConvert_H__
结果如下: