C语言简单实现:将C注释转化为C++注释

我们首先考虑一下都会出现什么情况:

C语言简单实现:将C注释转化为C++注释_#include

总结下来就是如下图:

C语言简单实现:将C注释转化为C++注释_#include_02

因此我们需要封装三个函数。

测试部分(test.c)如下:



#include"CommentConvert.h"

void test()
{
enum STATE state = NUL_STATE;
FILE *pfIn;
pfIn = fopen("input.c", "r");
if (pfIn == NULL)
{
perror("open file for read\n");
exit(EXIT_FAILURE);
}
FILE *pfOut;
pfOut = fopen("output.c", "w");
if (pfOut == NULL)
{
perror("close file for write\n");
fclose(pfIn);
exit(EXIT_FAILURE);
}

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;
}
}
fclose(pfIn);
fclose(pfOut);
}

int main()
{
test();
system("pause");
return 0;
}

CommentConvert.h如下:

#ifndef __COMMENT_CONVERT_H__
#define __COMMENT_CONVERT_H__

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>

enum STATE
{
END_STATE,
NUL_STATE,
C_STATE,
CPP_STATE
};

void DoNulState(FILE*pfIn, FILE*pfOut, enum STATE* s);

void DoCState(FILE*pfIn, FILE*pfOut, enum STATE* s);

void DoCppState(FILE*pfIn, FILE*pfOut, enum STATE* s);

#endif //__COMMENT_CONVERT_H__

CommentConvert.c如下:

#include"CommentConvert.h"

void DoNulState(FILE*pfIn, FILE*pfOut, enum STATE* s)
{
int first = fgetc(pfIn);
switch (first)
{
case '/':
{
int second = fgetc(pfIn);
switch (second)
{
case '*':
fputc('/', pfOut); //遇到'/*'转化为'//',进入C状态
fputc('/', pfOut);
*s = C_STATE;
break;
case '/': //遇到'//',进入C++状态,直接输出
fputc(first, pfOut);
fputc(second, pfOut);
*s = CPP_STATE;
break;
default: //遇到'/'又遇到文本,内容直接输出
fputc(first, pfOut);
fputc(second, pfOut);
break;
}
break;
}
case EOF: //文档结束
*s = END_STATE;
break;
default: //文本内容
fputc(first, pfOut);
break;
}
}

void DoCState(FILE *pfIn, FILE *pfOut, enum STATE* s) //C状态的处理
{
int first = fgetc(pfIn);
switch (first)
{
case '*':
{ int second = 0;
second = fgetc(pfIn);

if (second == '/') //遇到'*/',C注释结束
{
int third = 0;
third = fgetc(pfIn);

//注释结束判断是否换行,如果不是'\n',说明在second之后还有字符,因此需要换行
if (third != '\n')
{
fputc('\n', pfOut); //换行
ungetc(third, pfIn); //将读到的字符还给文档
*s = NUL_STATE;
}
else
{
fputc(third, pfOut);
*s = NUL_STATE;
}
}

else if (second == '*') //处理连续的**/问题
{
char third = fgetc(pfIn);
if (third == '/')
{
fputc(first, pfOut); //最后一个*与/结合注释结束
*s = NUL_STATE;
}
else
{
fputc(first, pfOut);
fputc(second, pfOut);
}
}
else //处理*后是文本的情况
{
fputc(first, pfOut);
fputc(second, pfOut);
}
break;
}
//如果'/*'后换行,转成C++必须换行后每行都加上注释
case '\n':
fputc(first, pfOut);
fputc('/',pfOut);
fputc('/', pfOut);
break;
case EOF:
*s = END_STATE;
break;
default:
fputc(first, pfOut);
break;
}
}

void DoCppState(FILE*pfIn, FILE*pfOut, enum STATE* s) //C++状态处理
{
int ch = fgetc(pfIn);
switch (ch)
{
case '\n':
fputc(ch, pfOut);
*s = NUL_STATE;
break;
case EOF:
*s = END_STATE;
break;
default:
fputc(ch, pfOut);
break;
}
}