单个.c文件的转换思路:
由一个input.c经过注释转换生成一个转化好的output.c文件
由C注释向C++注释转换可分为以下几种情况:
// 1.一般情况
int num = 0;
/* int i = 0; */
// 2.换行问题
/* int i = 0; */int j = 0;
/* int i = 0; */
int j = 0;
// 3.匹配问题
/int i = 0;/*xxxxx/
// 4.多行注释问题
/*
int i=0;
int j = 0;
int k = 0;
*/int k = 0;
// 5.连续注释问题
////
// 6.连续的**/问题
/*/
// 7.C++注释问题
// /xxxxxxxxxxxx/
各个状态之间的转换关系
一个文件中包含的内容包括:c注释、c++注释、正常代码、文件结束标志四个内容。具体转换关系如图:
具体代码如下:
头文件:Commentconvert.h
#ifndef __COMMENT_CONVERT_H__
#define __COMMENT_CONVERT_H__
#include<stdio.h>
#include<stdlib.h>
typedef enum State
{
NUL_STATE,
C_STATE,
CPP_STATE,
END_STATE
}State;
void Commentconvert(FILE* pfRead, FILE* pfWrite);
void DoNULState(FILE* pfRead, FILE* pfWrite, State* ps);
void DoCState(FILE* pfRead, FILE* pfWrite, State* ps);
void DoCPPState(FILE* pfRead, FILE* pfWrite, State* ps);
void DoENDState(FILE* pfRead, FILE* pfWrite, State* ps);
#endif//__COMMENT_CONVERT_H__
测试代码:test.c
#define _CRT_SECURE_NO_WARNINGS
#include"Commentconvert.h"
void test()
{
FILE *pfRead = NULL;
FILE *pfWrite = NULL;
pfRead = fopen("input.c", "r");
if (pfRead == NULL)
{
perror("openfile for read:");
exit(EXIT_FAILURE);
}
pfWrite = fopen("output.c", "w");
if (pfWrite == NULL)
{
perror("open file for write:");
exit(EXIT_FAILURE);
}
//注释转换
Commentconvert(pfRead, pfWrite);
fclose(pfRead);
pfRead = NULL;
fclose(pfWrite);
pfWrite = NULL;
}
int main()
{
test();
system("pause");
return 0;
}
实现代码:Commentconvert.c
#define _CRT_SECURE_NO_WARNINGS
#include"Commentconvert.h"
void Commentconvert(FILE* pfRead, FILE* pfWrite)
//状态机
{
State state = NUL_STATE;
while (state != END_STATE)
{
switch (state)
{
case NUL_STATE:
DoNULState(pfRead, pfWrite, &state);
break;
case C_STATE:
DoCState(pfRead, pfWrite, &state);
break;
case CPP_STATE:
DoCPPState(pfRead, pfWrite, &state);
break;
case END_STATE:
break;
}
}
}
void DoNULState(FILE* pfRead, FILE* pfWrite, State* ps)
{
int first = fgetc(pfRead);
switch (first)
{
case '/':
{
int second = fgetc(pfRead);
switch (second)
{
case '*':
{
//c状态
fputc('/', pfWrite);
fputc('/', pfWrite);
*ps = C_STATE;
}
break;
case '/':
{
//c++状态
fputc(first, pfWrite);
fputc(second, pfWrite);
*ps = CPP_STATE;
}
break;
default:
{
fputc(first, pfWrite);
fputc(second, pfWrite);
}
break;
}
}
break;
case EOF:
fputc(first, pfRead);
*ps = END_STATE;
break;
default:
fputc(first, pfWrite);
break;
}
}
void DoCState(FILE* pfRead, FILE* pfWrite, State* ps)
{
int first = fgetc(pfRead);
switch (first)
{
case '*':
{
int second = fgetc(pfRead);
switch (second)
{
case '/':
{
*ps = NUL_STATE;
int third = fgetc(pfRead);
if (third == '\n')//是否有换行
{
fputc(third, pfWrite);
}
else
{
fputc('\n', pfWrite);
ungetc(third, pfRead);
//补充了换行符,读取的第三个字符要还回去,避免丢失
}
}
break;
default:
{
fputc(first, pfWrite);
ungetc(second, pfRead);
}
break;
}
}
break;
case '\n':
{
fputc(first, pfWrite);
fputc('/', pfWrite);
fputc('/', pfWrite);
}
break;
default:
fputc(first, pfWrite);
break;
}
}
void DoCPPState(FILE*pfRead, FILE*pfWrite, State* ps)
{
int first = fgetc(pfRead);
switch (first)
{
case '\n':
{
fputc('\n', pfWrite);
*ps = NUL_STATE;
}
break;
case EOF:
{
fputc(first, pfWrite);
*ps = END_STATE;
}
break;
default:
fputc(first, pfWrite);
break;
}
}
测试结果: