题目要求:
要将全部的c语言风格的注释转换为c++风格的注释,如下图所示,需要将input.c文件经过注释转换程序转换为output.c文件所示
分析:
从input.c文件可以看书,每行开头遇见的内容有三种 // , /* ,其他代码。因此,这里就要分情况讨论。可以定义三个函数,分别处理NULL,C,C++对应状态。将 // 定义为CPP_STATE, /* 定义为 C_STATE状态,其他情况定义为NULL_STATE。下图给出了三者的转换关系:
应当注意的是:在C_STATE状态转换下,遇到*/后还应该考虑后边是否还有其他代码,以及在遇到 */之前会出现这种情况:*****/,还有遇到多行注释的情况(应该在每行开始加上 //)
具体代码如下:
"CommentCovert.h"
#ifndef _COMMENT_CONVERT_H__
#define _COMMENT_CONVERT_H__
#include<stdio.h>
#include<stdlib.h>
#define INPUTNAME "input.c"
#define OUTPUTNAME "ouput.c"
enum STATE
{
NUL_STATE,
C_STATE,
CPP_STATE,
END_STATE
};
void CommentConvert(FILE *pfRead,FILE *pfWrite);
void Do_NUL_State(FILE *pfRead,FILE *pfWrite);
void Do_C_State(FILE *pfRead,FILE *pfWrite);
void Do_Cpp_State(FILE *pfRead,FILE *pfWrite);
#endif // _COMMENT_CONVERT_H__
#define _CRT_SECURE_NO_WARNINGS
#include"CommentConvert.h"
enum STATE state = NUL_STATE;
void Do_NUL_State(FILE *pfRead,FILE *pfWrite) //遇到NULL状态下的处理
{
int first = 0;
int second = 0;
first = fgetc(pfRead);
switch(first)
{
case '/':
{
second = fgetc(pfRead);
if(second == '*') //NULL状态下遇到/*时将其置为//并进入C状态
{
fputc('/',pfWrite);
fputc('/',pfWrite);
state = C_STATE;
}
else if(second == '/') //NULL状态下遇到//时直接输出
{
fputc(first,pfWrite);
fputc(second,pfWrite);
state = CPP_STATE;
}
else //NULL状态下遇到/后又遇到其他字符将其直接输出
{
fputc(first,pfWrite);
fputc(second,pfWrite);
}
}
break;
case EOF:
state = END_STATE;
default :
fputc(first,pfWrite);
break;
}
}
void Do_Cpp_State(FILE *pfRead,FILE *pfWrite) //C++状态下的处理
{
int first = 0;
first = fgetc(pfRead);
switch(first)
{
case '\n': //CPP状态下遇到'\n',说明前一行注释已完成
fputc(first,pfWrite);
state = NUL_STATE;
break;
case EOF:
state = END_STATE;
break;
default:
fputc(first,pfWrite);
break;
}
}
void Do_C_State(FILE *pfRead,FILE *pfWrite) //C状态下的处理
{
int first = fgetc(pfRead);
int second = 0;
int third = 0;
switch(first)
{
case '*':
{
second = fgetc(pfRead);
if(second == '/') //匹配问题
{
third = fgetc(pfRead);
//多行注释与连续注释问题
if (third != '\n')
{
fputc('\n', pfWrite);
ungetc(third, pfRead);
}
else
{
fputc('\n', pfWrite);
}
state = NUL_STATE;
//如果'*/'之后不是'\n',说明在second之后还有字符,因此在此处输入一个换行,并将
//读到的third字符返回到pfRead中去,并将状态置为 NUL_STATE
//如果是'\n',说明c语言注释已完,下一个字符有可是‘/’也有可能是其他字符,因此
//将状态回到 NUL_STATE
}
else if(second == '*') //连续的**/问题
{
third = fgetc(pfRead);
fputc(first,pfWrite);
if(third == '/')
state = NUL_STATE;
}
else
{
fputc(first,pfWrite);
fputc(second,pfWrite);
}
}
break;
case '\n':
fputc(first,pfWrite);
fputc('/',pfWrite);
fputc('/',pfWrite);
break;
case EOF:
state = END_STATE;
break;
default:
fputc(first,pfWrite);
break;
}
}
void CommentConvert(FILE *pfRead,FILE *pfWrite)
{
while(state != END_STATE)
{
switch(state)
{
case NUL_STATE:
Do_NUL_State(pfRead,pfWrite);
break;
case C_STATE:
Do_C_State(pfRead,pfWrite);
break;
case CPP_STATE:
Do_Cpp_State(pfRead,pfWrite);
break;
case END_STATE:
break;
default:
break;
}
}
}
"test.c"
#define _CRT_SECURE_NO_WARNINGS
#include"CommentConvert.h"
int main()
{
FILE *pfRead = NULL;
FILE *pfWrite = NULL;
printf("转换开始\n");
pfRead = fopen(INPUTNAME,"r");
if(pfRead == NULL)
{
perror("open file for read");
exit(0);
}
pfWrite = fopen(OUTPUTNAME,"w");
if(pfWrite == NULL)
{
fclose(pfRead);
perror("open file for write");
exit(0);
}
CommentConvert(pfRead,pfWrite);
printf("转换结束\n");
system("pause");
return 0;
}