注释转换的功能:
可将注释方式总结为7中:
//1.一般情况
/* int i = 0; */
//2.换行问题
/* int i = 0; */ int j = 0;
/* int i = 0; */
int j = 0;
//3.匹配问题
/* int i = 0; /*xxxxxxx*/
//4.多行注释问题
/*
int i = 0;
int j = 0;
int k = 0;
*/int k = 0;
//5.连续注释问题
/**/ /**/
//6.连续**/问题
/***/
//7.c++注释问题
// /*xxxxxxxx*/
解题思路:把问题用有限状态机解决
代码如下:
//CommentConvert.h
#ifndef __COMMENTCOVERT_H__
#define __COMMENTCOVERT_H__
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#define INPUT_FILE "input.c"
#define OUTPUT_FILE "output.c"
enum STATE
{
NUL_STATE,
C_STATE,
CPP_STATE,
STR_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);
void DO_STR_STATE(FILE *pfRead, FILE *pfWrite);
#endif //__COMMENTCOVERT_H__
//CommentConvert.c
#include "CommentConvert.h"
enum STATE state = NUL_STATE;
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 STR_STATE:
DO_STR_STATE(pfRead, pfWrite);
break;
case END_STATE:
break;
}
}
}
void DO_NUL_STATE(FILE *pfRead, FILE *pfWrite)
{
int first = 0;
int second = 0;
first = fgetc(pfRead);
switch (first)
{
case '/':
second = fgetc(pfRead);
if (second == '/')
{
fputc('/', pfWrite);
fputc('/', pfWrite);
state = CPP_STATE;//无状态下遇到 //, 直接将 // 写入,并进入CPP状态
}
else if (second == '*')
{
fputc(first,pfWrite);
fputc('/', pfWrite);
state = C_STATE;//无状态下遇到 /* ,将 /* 变成 // 写入,并进入C状态
}
else
{
fputc(first, pfWrite);
fputc(second, pfWrite);//遇到其他的字符,直接写入,不改变状态
}
break;
case EOF:
state = END_STATE;//遇到 EOF ,进入结束状态
break;
case '"':
fputc(first, pfWrite);
state = STR_STATE;//如果遇到 ”,进入字符串状态
break;
default:
fputc(first, pfWrite);
break;
}
}
void DO_C_STATE(FILE *pfRead, FILE *pfWrite)
{
int first = 0;
int second = 0;
int third = 0;
first = fgetc(pfRead);
switch (first)
{
case '*':
second = fgetc(pfRead);
if (second == '/')//遇到 */ ,表示c的注释结束,进入无状态
{
state = NUL_STATE;
third = fgetc(pfRead);
if (third != '\n')
{
fputc('\n', pfWrite);//如果 */ 后面不是回车,则写入回车,然后把读到的字符放回
ungetc(third, pfRead);
}
else
{
ungetc(third, pfRead);//如果 */ 后面是回车,把回车放回
}
}
else //.......
{
fputc(first, pfWrite);
ungetc(second, pfRead);
}
break;
case '\n':
fputc(first, pfWrite);
fputc('/', pfWrite);
fputc('/', pfWrite);
break;
default:
fputc(first, pfWrite);
break;
}
}
void DO_CPP_STATE(FILE *pfRead, FILE *pfWrite)
{
int first = 0;
int second = 0;
first = fgetc(pfRead);
switch (first)
{
case '\n':
fputc(first, pfWrite);//CPP状态,遇到回车,则进入无状态
state = NUL_STATE;
break;
default:
if (first == EOF)
{
state = END_STATE;
}
else
{
fputc(first, pfWrite);
}
break;
}
}
void DO_STR_STATE(FILE *pfRead, FILE *pfWrite)
{
int first = 0;
first = fgetc(pfRead);
switch (first)
{
case '"':
fputc(first, pfWrite);
state = NUL_STATE;
break;
default:
fputc(first, pfWrite);
break;
}
}
//test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"CommentConvert.h"
int main()
{
FILE *pfRead = NULL;
FILE *pfWrite = NULL;
pfRead = fopen(INPUT_FILE, "r");
if (pfRead == NULL)
{
perror("open file for read");
exit(EXIT_FAILURE);
}
pfWrite = fopen(OUTPUT_FILE, "w");
if (pfWrite == NULL)
{
perror("open file for write");
fclose(pfRead);
exit(EXIT_FAILURE);
}
commentconvert(pfRead, pfWrite);
fclose(pfRead);
fclose(pfWrite);
system("pause");
return 0;
}