分析思路:状态转换
将注释分为 常规状态(null),C语言状态(/*), Cpp状态(//)
用三种状态的转换来分析复杂多样的注释情况;
Commentconvert.h
#ifndef __COMMENTCONVERT_H__
#define __COMMENTCONVERT_H__
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
typedef enum STATE
{
NULL_STATE,
C_STATE,
CPP_STATE,
END_STATE,
}STATE;
void DoConverWork(FILE *pfin, FILE *pfout); //转换工作函数
void DoNULLState(FILE *pfin, FILE *pfout, STATE *ps); //空状态处理
void DoCState(FILE *pfin, FILE *pfout, STATE *ps); //C状态处理
void DoCPPState(FILE *pfin, FILE *pfout, STATE *ps); //Cpp状态处理
#endif //__COMMENTCONVERT_H__
#include "CommentConvert.h"
void DoConverWork(FILE *pfin, FILE *pfout)//转换工作函数
{
STATE state = NULL_STATE;
while (state != END_STATE)
{
switch (state)
{
case NULL_STATE:
DoNULLState(pfin, pfout, &state);
break;
case C_STATE:
DoCState(pfin, pfout, &state);
break;
case CPP_STATE:
DoCPPState(pfin, pfout, &state);
break;
}
}
}
void DoNULLState(FILE *pfin, FILE *pfout, STATE *ps)
{
int first = 0;
first = fgetc(pfin);
switch (first)
{
case '/':
{
int second = 0;
second = fgetc(pfin);
switch (second)
{
case '*'://c状态
{
fputc('/', pfout);
fputc('/', pfout);
*ps = C_STATE; //指向C处理
}
break;
case '/'://cpp状态
{
fputc(first, pfout);
fputc(second, pfout);
*ps = CPP_STATE;//指向cpp处理
}
break;
default:
break;
}
}
break;
case EOF:
*ps = END_STATE;
break;
default:
fputc(first, pfout);
break;
}
}
void DoCState(FILE *pfin, FILE *pfout, STATE *ps) //c状态
{
int first = 0;
first = fgetc(pfin);
switch (first)
{
case '*':
{
int second = fgetc(pfin);
switch (second)
{
case '/':
fputc('\n', pfout);
*ps = NULL_STATE;
break;
default:
fputc(first, pfout);
ungetc(second, pfin);//返回*之后的字符 以防出现**/
}
}
break;
case '\n':
{
fputc('\n', pfout);
fputc('/', pfout);
fputc('/', pfout);
}
break;
default:
fputc(first, pfout);
break;
}
}
void DoCPPState(FILE *pfin, FILE *pfout, STATE *ps)//cpp状态
{
int first = 0;
first = fgetc(pfin);
switch (first)
{
case '\n':
fputc('\n', pfout);
*ps = NULL_STATE;
break;
case EOF:
*ps = END_STATE;
break;
default:
fputc(first, pfout);
}
}
test.c
#include "CommentConvert.h"
#define IN_FILENAME "input.c"
#define OUT_FILENAME "output.c"
int main()
{
FILE * pfwrite = NULL;
FILE * pfread = NULL;
pfread = fopen(IN_FILENAME, "r");
if (pfread == NULL)
{
perror("open file for read");
exit(EXIT_FAILURE);
}
pfwrite = fopen(OUT_FILENAME, "w");
if (pfwrite == NULL)
{
perror("open file for write");
exit(EXIT_FAILURE);
}
DoConverWork(pfread, pfwrite);
fclose(pfread);
fclose(pfwrite);
return 0;
}