7种转换情况
1.一般情况
/*int i = 0;*/
2.换行问题
/*int i = 0;*/int j = 0;
/*int i = 0*/
3.匹配问题
/*int i = 0;/* int j = 0;*/
4.多行注释问题
/*
int i = 0
int j = 0
*/int k = 0;
5.连续注释问题
/*int i = 0;*//*int j = 0;*/
6.连续的**/问题
/*int i = 0;**/
7.C++注释问题
// /* int i = 0;*/
分析
我们可以看到注释转换需要考虑的情况非常多的,这对于我们写程序是非常不利的,为了解决这个问题 我们引入了有限状态机的概念,
有限状态机简称状态机,是表示有限个状态以及在这些状态之间转移的行为的模型。有限状态是闭环系统,可以用有限的状态处理无穷的状态
由此引入下面这张图
代码实现
Convert.h
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef enum CONVERT_STATE
{
NORMAL_STATUS,
C_STATUS,
CPP_STATUS,
END_STATUS,
}StateType;
void convertBegin();
void convertStatusMachine(FILE *in, FILE *out);
void doCPPStatus(FILE *in, FILE *out);
void doCStatus(FILE *in, FILE *out);
void doNormal(FILE *in, FILE *out);
Convert.c
#include"Convert.h"
//1,我们要声明一个枚举(enum)类型来存放四种状态
//定义全局变量state,初始状态为NULL_STATE.
StateType gStatus = NORMAL_STATUS;
//2,声明一个打开input.c和output.c的函数
void convertBegin()
{
FILE *in = fopen("input.c", "r");
if (NULL == in)
{
perror("fopen");
exit(1);
}
FILE *out = fopen("output.c", "w");
if (NULL == out)
{
perror("fopen");
exit(2);
}
convertStatusMachine(in, out);
fclose(in);
fclose(out);
}
//3,声明一个切换状态的函数
void convertStatusMachine(FILE *in, FILE *out)
{
assert(in);
assert(out);
while (gStatus != END_STATUS)
{
switch (gStatus)
{
case NORMAL_STATUS:
doNormal(in, out);
break;
case C_STATUS:
doCStatus(in, out);
break;
case CPP_STATUS:
doCPPStatus(in, out);
break;
case END_STATUS:
break;
default:
break;
}
}
}
// 4,我们还要声明处理不同状态的函数 处理NULL_STATE的函数:
void doNormal(FILE *in, FILE *out)
{
int first = fgetc(in);
int second = 0;
assert(in);
assert(out);
switch (first)
{
case '/':
{
second = fgetc(in);
if (second == '*')
{
fputc('/', out);
fputc('/', out);
gStatus = C_STATUS;
}
else if (second == '/')
{
fputc(first, out);
fputc(second, out);
gStatus = CPP_STATUS;
}
else
{
fputc(first, out);
fputc(second, out);
}
}
break;
case EOF:
gStatus = END_STATUS;
break;
default:
fputc(first, out);
break;
}
}
//处理C_STATE的的函数 /*...*/可以注释多行
void doCStatus(FILE *in, FILE *out)
{
int first = fgetc(in);
int second = 0;
assert(in);
assert(out);
switch (first)
{
case '*'://表示C语言注释状态 可能会结束
{
second = fgetc(in);
if (second == '/')
{
int third = fgetc(in);
if (third == '\n')
{
fputc(third, out);
}
else
{
fputc('\n', out);
ungetc(third, in);
gStatus = NORMAL_STATUS;
}
}
else
{
fputc(first, out);
ungetc(second, in);//将多余用来判断的字符撤销
}
}
break;
case '\n':
fputc(first, out);
fputc('/', out);
fputc('/', out);
break;
case EOF:
gStatus = END_STATUS;
break;
default:
fputc(first, out);
break;
}
}
//处理CPP_STATE的函数,只能注释一行
void doCPPStatus(FILE *in, FILE *out)
{
int first = fgetc(in);
assert(in);
assert(out);
int second = 0;
switch (first)
{
case '\n':
fputc(first, out);
gStatus = NORMAL_STATUS;
break;
case EOF:
gStatus = END_STATUS;
break;
default:
fputc(first, out);
break;
}
}
int main()
{
convertBegin();
printf("转换完成。\n");
system("pause");
return 0;
}