本文是将文件里面的C风格的注释,转换为CPP风格的注释。
C 的注释:/* XXX */
CPP 的注释://
转换时所有的情况如下图:
题目分析:
1、开始时,先将状态赋为空状态;
2、当遇到‘ /*
’时进入C状态,将‘/*
’ 改为‘//
’;
再次遇到‘*/
’时,C状态结束,如果后面是‘\n
’,则原
样输出;
若不是,则需要加上‘\n
’,再输出;
如果在‘/*
’之后有多个‘*
’则需要边读取边退回(ungetc)
3、当遇到‘//
’时,不需要做任何处理,直接输出;
4、当遇到‘EOF
’则结束。
测试代码如下图:
将左图的所有C语言注释转换为C++的注释;
下面是解决此问题的代码:
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 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 //具体函数的实现
#define _CRT_SECURE_NO_WARNINGS 1
#include"CommentConvert.h"
void DoNulState(FILE*pfIn, FILE*pfOut, enum STATE* s)
{
int first = 0;
first = fgetc(pfIn);
switch(first)
{
case'/':
{
int second = fgetc(pfIn);
switch (second)
{
case'/':// '//'为C++状态,直接输出
{
fputc(first, pfOut);
fputc(second, pfOut);
*s = CPP_STATE;
}
break;
case'*':
{
fputc(first, pfOut);
fputc('/', pfOut); //把'/*'转换为'//',C状态 需转换
*s = C_STATE;
}
break;
default:
fputc(first, pfOut);
fputc(second, pfOut);
break;
}
}
break;
case EOF:
fputc(first, pfOut);
*s = END_STATE;
break;
default:
fputc(first, pfOut);
break;
}
}
void DoCState(FILE*pfIn, FILE*pfOut, enum STATE* s)
{
int first = 0;
first = fgetc(pfIn);
switch (first)
{
case'*':
{
int second = fgetc(pfIn);
switch (second)
{
case'/':
{
int third = fgetc(pfIn);
if (third == '\n')
{
fputc(third, pfOut);
}
else
{
fputc('\n', pfOut);// 遇到'*/'时 与前面的‘/*’作用注释其中的内容,
//fputc(third, pfOut); // 而如果'*/'后不是‘\n’则需要加上换行
ungetc(third, pfIn);
}
*s = NUL_STATE;
}
break;
case '*':
{
//int third = getc(pfIn);
ungetc(second, pfOut);//ungetc: 把一个字符退回到输入流中
//防止多个'*'连用时'*/'中的*被提前读取
fputc(first, pfOut); //fputc : 送一个字符到一个流中
}
break;
default:
fputc(first, pfOut);
fputc(second, pfOut);
break;
}
}
break;
case '/':
//由于已经在C状态了,所以遇到‘/’时任然为正常代码
*s = NUL_STATE;
break;
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)
{
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);
break;
}
}
test.c //测试代码
#define _CRT_SECURE_NO_WARNINGS 1
#include"CommentConvert.h"
void test()
{
FILE *pfIn = NULL;
FILE *pfOut = NULL;
enum STATE state;
state = NUL_STATE;
pfIn = fopen("input.txt", "r");
if (pfIn == NULL)
{
perror("open file for read\n");
exit(EXIT_FAILURE);
}
pfOut = fopen("output.txt", "w");
if (pfOut == NULL)
{
perror("open 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;
default:
break;
}
}
fclose(pfIn);
fclose(pfOut);
}
int main()
{
test();
getchar();
return 0;
}