我们知道注释转换中有分为四个模式 NUL_格式(开始读取注释)、c格式、c++格式、END格式 (结束程序)。下面我用一张图来解释如下的关系。
该图清晰地展示了这四种格式的关系,下面用代码来实现上图。
CommentConvert.h
#define _CRT_SECURE_NO_WARNINGS 1
#ifndef __COMMENT_CONVERT_H__
#define __COMMENT_CONVERT_H__
#include<stdio.h>
#include<stdlib.h>
enum State
{
END_State,
NUL_State,
C_State,
CPP_State
};
void DocommentConvert(FILE*pfin, FILE*pfout);//声明,开始转换
void DoNulState(FILE*pfin, FILE*pfout, enum State*s);//指针接收);//NUL_格式
void DoCState(FILE*pfin, FILE*pfout, enum State*s);//c格式
void DoCppState(FILE*pfin, FILE*pfout, enum State*s);//c++格式
#endif // __COMMENT_CONVERT_H__
CommentConvert.c
#include"CommentConvert.h"
enum State state = NUL_State;
void DocommentConvert(FILE*pfin, FILE*pfout)
{
while (state != END_State)
{
switch (state)
{
case NUL_State:
DoNulState(pfin, pfout, &state);
break;
case C_State:
DoCState(pfin, pfout, &state);
break;
case CPP_State:
DoCppState(pfin, pfout, &state);
break;
default:
break;
}
}
}
void DoNulState(FILE*pfin, FILE*pfout, enum State*s)
{
int first = 0;
first = fgetc(pfin); //读取第一个字符
switch (first)
{
case '/':
{
int second = 0;
second = fgetc(pfin);
switch (second)
{
case '*': //进入c模式
fputc('/', pfout);
fputc('/', pfout);
*s = C_State;
break;
case '/': //进入cpp格式
fputc(first, pfout);
fputc(second, pfout);
*s = CPP_State;
break;
default: //其他格式如/int j=0;
ungetc(second, pfin);
*s = NUL_State;
break;
}
break;
}
case EOF: //为EOF时结束
*s = END_State;
break;
default: //其他情况下 普通 字符 写到 pfOut流中
fputc(first, pfout);
*s = NUL_State;
break;
}
}
void DoCState(FILE*pfin, FILE*pfout, enum State*s)
{
int first = 0;
int second = 0;
int third = 0;
first = fgetc(pfin);
switch (first)
{
case '*':
{
second = fgetc(pfin);
switch (second)
{
case '/': //表示c的形式结束
third = fgetc(pfin); // 获取第三个字符,用来判断连续注释以及换行问题
if ((third != '\n') && (third != EOF))
ungetc(third, pfin);
fputc('\n', pfout);// */
*s = NUL_State;
break;
default: // ****/
ungetc(second, pfin);
fputc(first, pfout);
*s = C_State;
break;
}
break;
}
case '\n': //多行注释
fputc('\n', pfout);
fputc('/', pfout);
fputc('/', pfout);
*s = C_State;
break;
default:
fputc(first, pfout);
*s = C_State;
break;
}
}
void DoCppState(FILE*pfin, FILE*pfout, enum State*s)
{
int first = 0;
first = fgetc(pfin);
switch (first)
{
case '\n':
fputc(first, pfout);
*s = NUL_State;
break;
case EOF: //结束标志
*s = END_State;
break;
default:
fputc(first, pfout);
*s = CPP_State;
break;
}
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"CommentConvert.h"
void test()
{
FILE* pfin = fopen("input.c.txt", "r"); //打开input.c流
if (pfin == NULL)
{
perror("open file of read");
exit(EXIT_FAILURE);
}
FILE* pfout = fopen("output.c.txt", "w");//打开 output.c流
if (pfout == NULL)
{
perror("open file of write");
exit(EXIT_FAILURE);
}
DocommentConvert(pfin, pfout);
fclose(pfin);
fclose(pfout);
}
int main()
{
test();
system("pause");
return 0;
}
下面为结果界面:
由此可看出注释转换的部分。
此次程序所需注意的地方:
1、建立文件的部分一定要注意 在之后要调用开始转换的那个函数,并且要注意fopen与fclose要连用,缺一不可。
2、在CommentConvert.c部分要注意cpp部分的转换,在其中第一个元素为’/’的情况在Nul的函数中已经考虑了一次,所以在cpp中要考虑另外的几种状况。
本人是新手,可能其中有些问题,希望给予意见或建议。