由上图可知:C语言注释转换主要分为四个状态:Nul_STATE(空状态)、C_STATE(C注释状态)、Cpp_STATE(C++注释状态)和End_STATE(结束状态);
重要的是要分清每个状态结束的条件以及各个状态相互转换的边界条件,然后对其作具体情况的分析处理;所以我用了三个函数DoNulcomment()、DoCcomment()和DoCppcomment()进行注释转换;为了思路更加清晰,在程序实现的时候用了三个文件函数,具体代码如下:
CommentConvert.h
#ifndef __CommentConvert_H__
#define __CommentConvert_H__
#include<stdio.h>
#include<stdlib.h>
typedef enum STATE//状态
{
End_STATE,
Nul_STATE,
C_STATE,
Cpp_STATE,
}STATE;
void ConvertWork(FILE*pfIn, FILE*pfOut);//工作函数
void DoNulcomment(FILE *pfIn, FILE *pfOut, STATE*s);//无状态函数处理
void DoCcomment(FILE *pfIn, FILE *pfOut, STATE*s);//c注释部分处理
void DoCppcomment(FILE *pfIn, FILE *pfOut, STATE*s);//cpp注释状态处理
#endif
CommentConvert.c
#define _CRT_SECURE_NO_WARNINGS 1#include"CommentConvert.h"void ConvertWork(FILE*pfIn, FILE*pfOut){ STATE state = Nul_STATE; while (state!=End_STATE) { switch (state) { case Nul_STATE: DoNulcomment(pfIn,pfOut,&state); break; case C_STATE: DoCcomment(pfIn, pfOut, &state); break; case Cpp_STATE: DoCppcomment(pfIn, pfOut, &state); break; } }}void DoNulcomment(FILE *pfIn, FILE *pfOut,STATE*s){int first = 0;first = fgetc(pfIn);switch (first){case'/':{ int second = 0; second = fgetc(pfIn); switch (second) { case'/'://cpp状态 { fputc(first, pfOut); fputc(second, pfOut); *s = Cpp_STATE; } break; case'*'://c状态 { fputc(first, pfOut); fputc('/', pfOut); *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 DoCcomment(FILE *pfIn, FILE *pfOut, STATE*s){int first = 0;first = fgetc(pfIn);switch (first){case '*':{int second = 0;second = fgetc(pfIn);switch (second){case'/':{ int third = fgetc(pfIn); if (third == '\n') { *s = Nul_STATE; fputc(third, pfOut); } else { fputc('\n', pfOut); ungetc(third, pfIn); // fputc(third, pfOut); *s = Nul_STATE; } break;}case'*': ungetc('*', pfIn); fputc(first, pfOut); break;default:fputc(first, pfOut);fputc(second, pfOut);break;}}break;case'/':{ int second = 0; second = fgetc(pfIn); switch (second) { case'/': { fputc(first, pfOut); fputc(second, pfOut); *s = Cpp_STATE; } break; default: fputc(first, pfOut); fputc(second, pfOut); break; }}break;case '\n':{ int third = fgetc(pfIn); fputc(first, pfOut); if (third == '*') { ungetc('*', pfIn); } else { fputc('/', pfOut); fputc('/', pfOut); } break;}default:fputc(first, pfOut);break;}}void DoCppcomment(FILE *pfIn, FILE *pfOut, STATE*s){int first = 0;first = fgetc(pfIn);switch (first){case'/':{ int second = 0; second = fgetc(pfIn); switch (second) { case'/': fputc(first, pfOut); fputc(second, pfOut); *s = Cpp_STATE; break; default: fputc(first, pfOut); fputc(second, pfOut); break; }}break;case'*':{ int second = 0; second = fgetc(pfIn); switch (second) { case'/': { fputc(first, pfOut); fputc(second, pfOut); //fputc('\n', pfOut); *s = Nul_STATE; break; } case'*': { ungetc('*', pfIn); fputc(first, pfOut); break; } default: fputc(first, pfOut); fputc(second, pfOut); break; }}break;case '\n':*s = Nul_STATE;fputc(first, pfOut);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;
pfIn = fopen("input.c", "r");
pfOut = fopen("pfout.c", "w");
if (pfIn == NULL)
{
perror("file for fopen");
exit(EXIT_FAILURE);
}
if (pfOut == NULL)
{
perror("fopen");
fclose(pfIn);
exit(EXIT_FAILURE);
}
ConvertWork(pfIn, pfOut);
fclose(pfIn);
fclose(pfOut);
}
int main()
{
test();
system("pause");
return 0;
}
结果展示: