commentConvert.h
#ifndef _COMMENT_CONVERT_H__
#define _COMMENT_CONVERT_H__
#include<stdio.h>
#include<stdlib.h>
enum State
{
NUL_STATE,//无注释状态
C_STATE,//C语言注释状态
CPP_STATE,//C++注释状态
END_STATE//代码结束状态
};
void DoCommentConvert(FILE* pfIn, FILE* pfOut);
void DoNulState(FILE* pfIn, FILE* pfOut, enum State* ps);
void DoCState(FILE* pfIn, FILE* pfOut, enum State* ps);
void DoCppState(FILE* pfIn, FILE* pfOut, enum State* ps);
#endif //_COMMENT_CONVERT_H__
commentConvert.c
#include "commentConvert.h"
void DoCommentConvert(FILE* pfIn, FILE* pfOut)
{
enum State state = NUL_STATE;//初始化状态 为 无注释状态
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;
case END_STATE:
break;
}
}
}
//无状态转换
void DoNulState(FILE* pfIn, FILE* pfOut, enum State* ps)
{
int first = fgetc(pfIn);//从文件中读取一个字符来判断
switch(first)
{
case '/'://表示要进入注释状态
{
int second = fgetc(pfIn);//再从文件中读取一个字符来判断
switch(second)
{
case '*'://表示代码是 /* 表示进入C语言注释状态
{
fputc('/',pfOut);//将它改为C++注释 输出到文件
fputc('/',pfOut);
*ps = C_STATE;//状态转换为 C注释状态
}
break;
case '/'://表示代码是 // 表示进入C++注释状态
{
fputc(first,pfOut);//将注释输出到文件
fputc(second,pfOut);
*ps = CPP_STATE;//状态转换为 C++注释状态
}
break;
default: //表示这个'/ '是字符
{
fputc(first,pfOut);//将读取到的字符输出到文件
fputc(second,pfOut);
}
break;
}
}
break;
case EOF://遇到EOF表示代码结束
{
*ps = END_STATE;//状态改为 END
}
break;
default://表示遇到的不是注释 ,状态不变
{
fputc(first,pfOut);//将读取的字符输出到文件
}
break;
}
}
//c语言状态转换
void DoCState(FILE* pfIn, FILE* pfOut, enum State* ps)
{
int first = fgetc(pfIn);
switch(first)
{
case '*'://遇到'*'表示C语言注释状态 可能会结束
{
int second = fgetc(pfIn);
switch(second)
{
case '/'://表示 C语言注释 结束 但要判断之后是不是'\n',因为C++注释是以换行结束的
{
int third = fgetc(pfIn);
if(third == '\n')//如果是'\n'
{
ungetc(third,pfIn);//把回车放回
}
else
{
fputc('\n',pfOut);//如果不是 ,我们要帮他换行
ungetc(third,pfIn);//并且要将用来判断的字符 从读取流中的撤销 ,防止下次判断时 少判断一个字符
}
*ps = NUL_STATE;//状态装换为无注释状态
}
break;
default: //如果遇到*,但是后边不是/,把*放进去,*后边的字符放回,比如,/***/,进入c状态以后,
//遇到*,后边的字符也是*,如果把两个*都写进去,后边就只剩下/,就不能找到c状态结束的标志,
//所以,需要把第二个字符原样写回
{
fputc(first,pfOut);
ungetc(second,pfIn);
}
break;
}
}
break;
case '\n'://换行之后要加上 // 因为C++只注释能一行
{
fputc(first,pfOut);
fputc('/',pfOut);
fputc('/',pfOut);
}
break;
default://否则直接输出
{
fputc(first,pfOut);
}
break;
}
}
//c++语言状态转换
void DoCppState(FILE* pfIn, FILE* pfOut, enum State* ps)
{
int ch = fgetc(pfIn);
switch(ch)
{
case '\n':
fputc(ch,pfOut);//cpp状态,如果遇到回车,cpp状态结束,进入无状态
*ps = NUL_STATE;
break;
case EOF:
*ps = END_STATE;
break;
default:
fputc(ch,pfOut);
break;
}
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "commentConvert.h"
void test()
{
FILE* pfIn = NULL;
FILE* pfOut = NULL;
pfIn = fopen("input.c","r");
if(pfIn == NULL)
{
perror("open file for read");
exit(EXIT_FAILURE);
}
pfOut = fopen("output.c","w");
if(pfOut == NULL)
{
fclose(pfIn);
perror("open file for write");
exit(EXIT_FAILURE);
}
//注释转换
DoCommentConvert(pfIn,pfOut);
fclose(pfIn);
pfIn = NULL;
fclose(pfOut);
pfOut = NULL;
printf("转换成功\n");
}
int main()
{
test();
return 0;
}