版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zzb2019/article/details/82081532
注释转换
- C++风格的注释//注释转换为标准C分风格/* */注释
- /* */风格的注释保持原样
- 所有的转换需要符合语法规则
- 注释转换需要支持注释嵌套
一.注释的嵌套情形很多,这里只是举例,你需要遵照C/C++语言的注释规则来编写代码,我不会仅测试这里的例子。
1、单行注释或没有嵌套,注释行直接转换,如:
①//123 /* 123 */
②/* 123 */ /* 123 */ 不变
③/*123
*/ 保持原样
2、有嵌套的注释(一个注释中还有嵌套其他注释符号//,/* */)嵌套中多余的每个注释符号用两个空格代替。
二.
1、除以下两种情况的修改,源文件转换后不能有任何其它的修改:
①多余的注释符用空格代替
②//在注释开始替换为/* ,行尾增加*/
2、下面的3种情形无需转换
① /* 123 */ /* 456 */
②/* 123 */ /* 456
*/
③/* 123
*/ /* 456
*/
3、不需要考虑输入文件中不符合语法规则的注释
untili.h 中包含用到的头文件 和状态的定义
#ifndef _CONVERT_CONMMENT_H
#define _CONVERT_CONMMNET_H
#include<iostream>
#include<stdio.h>
using namespace std;
typedef enum
{
ARGUMENT_ERROR = -1,
OPEN_ERROR = -2,
OK = 0,
}STATUS;
// time
// 有限状态机
// 事件驱动
// 状态:NO CPP C END 四种状态
//c -> c++ : 注释qian tao
//c->END c++ ->END NO->END : EOF
//
#endif
CovertComment.h 为 转换工具的头文件,状态的定义,及函数的声明
//ConvertComment.h
#ifndef _CONVERT_COMMENT_H
#define _CONVERT_COMMENT_H
#include"utili.h"
typedef enum
{
NO_COMMENT_STATE,
CPP_COMMENT_STATE,
C_COMMENT_STATE,
STR_COMMENT_STATE,
END_STATE,
}STATE_ENUM;
typedef struct
{
FILE *inputfile;
FILE *outputfile;
STATE_ENUM ulstate;
}STATE_MACHINE;
STATUS ConvertComment(FILE *inputfile,FILE *outputfile);
void EventPro(char ch);
void EventProAtCpp(char ch);
void EventProAtC(char ch);
void EventProAtNo(char ch);
void EventProcAtStr(char ch);
#endif
CovertComment.cpp
#include"ConvertComment.h"
//这是为了解决//abc"xy//z" 最后一次回退到上一层的状态
static STATE_ENUM g_str_pre_state;
static STATE_MACHINE g_state;//全局状态机
STATUS ConvertComment(FILE *inputfile, FILE *outputfile)
{
if (inputfile == NULL || outputfile == NULL)
{
// printf("Argument Is Invalid.\n");
cout << "Argument is invalid" << endl;
return ARGUMENT_ERROR;
}
//初始化状态机器
g_state.inputfile = inputfile;
g_state.outputfile = outputfile;
g_state.ulstate = NO_COMMENT_STATE;
char ch;
while (g_state.ulstate != END_STATE)
{
ch = fgetc(g_state.inputfile);
EventPro(ch);
}
return OK;
}
void EventPro(char ch) //事件处理函数
{
switch (g_state.ulstate)
{
case NO_COMMENT_STATE:
EventProAtNo(ch);
break;
case CPP_COMMENT_STATE:
EventProAtCpp(ch);
break;
case C_COMMENT_STATE:
EventProAtC(ch);
break;
case STR_COMMENT_STATE:
EventProcAtStr(ch);
break;
}
}
void EventProAtNo(char ch)
{
char nextch;
switch (ch)
{
case '/':
nextch = fgetc(g_state.inputfile);
if (nextch == '/') //c++ Comment
{
fputc('/', g_state.outputfile);
fputc('*', g_state.outputfile);
g_state.ulstate = CPP_COMMENT_STATE;
}
else if (nextch == '*') //C* Comment
{
fputc('/', g_state.outputfile);
fputc('*', g_state.outputfile);
g_state.ulstate = C_COMMENT_STATE;
}
else
{
fputc(ch, g_state.outputfile);
}
break;
case'\n':
fputc('\n', g_state.outputfile);
break;
case '"':
fputc(ch, g_state.outputfile);
g_str_pre_state = NO_COMMENT_STATE;
g_state.ulstate = STR_COMMENT_STATE;
break;
case '*':
fputc(ch, g_state.outputfile);
break;
case EOF:
g_state.ulstate = END_STATE;
break;
default:
fputc(ch, g_state.outputfile);
break;
}
}
void EventProAtCpp(char ch)
{
char nextch;
char three;
switch (ch)
{
case EOF:
fputc('*', g_state.outputfile);
fputc('/', g_state.outputfile);
g_state.ulstate = END_STATE;
break;
case '\n':
fputc('*', g_state.outputfile);
fputc('/', g_state.outputfile);
fputc('\n', g_state.outputfile);
g_state.ulstate = NO_COMMENT_STATE;
break;
case '*':
nextch = fgetc(g_state.inputfile);
if (nextch == '/')
{
fputc(' ', g_state.outputfile);
fputc(' ', g_state.outputfile);
}
else
{
fputc(ch, g_state.outputfile);
fputc(nextch, g_state.outputfile);
}
break;
case '/':
nextch = fgetc(g_state.inputfile);
if (nextch == '/')
{
fputc(' ', g_state.outputfile);
fputc(' ', g_state.outputfile);
three = fgetc(g_state.inputfile);
while (three == '/')
{
fputc(' ', g_state.outputfile);
three = fgetc(g_state.inputfile);
}
fputc(three, g_state.outputfile);
}
else if (nextch == '*')
{
fputc(' ', g_state.outputfile);
fputc(' ', g_state.outputfile);
}
else
{
fputc(ch, g_state.outputfile);
fputc(nextch, g_state.outputfile);
}
break;
case '"':
fputc(ch, g_state.outputfile);
g_str_pre_state = CPP_COMMENT_STATE;
g_state.ulstate = STR_COMMENT_STATE;
break;
default:
fputc(ch, g_state.outputfile);
break;
}
}
void EventProAtC(char ch) /* */
{
char nextch;
switch (ch)
{
case '*':
nextch = fgetc(g_state.inputfile);
while (nextch == '*')
{
fputc(nextch, g_state.outputfile);
nextch = fgetc(g_state.inputfile);
}
if (nextch == '/')
{
fputc('*', g_state.outputfile);
fputc('/', g_state.outputfile);
g_state.ulstate = NO_COMMENT_STATE;
}
else if (nextch == '*')
{
fputc('*', g_state.outputfile);
fputc('*', g_state.outputfile);
}
else
{
fputc(ch, g_state.outputfile);
fputc(nextch, g_state.outputfile);
}
break;
case EOF:
fputc('*', g_state.outputfile);
fputc('/', g_state.outputfile);
g_state.ulstate = END_STATE;
break;
case '/': /* // */
nextch = fgetc(g_state.inputfile);
//next_nextch = fgetc(g_state.inputfile);
if (nextch == '/' /*&& next_nextch=='/'*/)
{
fputc(' ', g_state.outputfile);
fputc(' ', g_state.outputfile);
}
else if (nextch == '\n')
{
fputc('\n', g_state.outputfile);
}
break;
case '"':
fputc(ch, g_state.outputfile);
g_str_pre_state = C_COMMENT_STATE;
g_state.ulstate = STR_COMMENT_STATE;
break;
default:
fputc(ch, g_state.outputfile);
break;
}
}
void EventProcAtStr(char ch)
{
char nextch, three;
switch (ch)
{
case '"':
fputc(ch, g_state.outputfile);
g_state.ulstate = g_str_pre_state;
break;
case '*':
nextch = fgetc(g_state.inputfile);
if (nextch = '/')
{
fputc(ch, g_state.outputfile);
fputc(nextch, g_state.outputfile);
three = fgetc(g_state.inputfile);
if (three == '\n')
{
fputc('\n', g_state.outputfile);
g_state.ulstate = NO_COMMENT_STATE;
}
else
{
fputc(three, g_state.outputfile);
}
}
else
{
fputc(ch, g_state.outputfile);
fputc(nextch, g_state.outputfile);
}
break;
case '/':
nextch = fgetc(g_state.inputfile);
if (nextch == '*')
{
fputc('/', g_state.outputfile);
fputc('*', g_state.outputfile);
}
else if (nextch == '/')
{
fputc('/', g_state.outputfile);
fputc('/', g_state.outputfile);
}
else
{
fputc(ch, g_state.outputfile);
fputc(nextch, g_state.outputfile);
}
break;
case EOF:
fputc('*', g_state.outputfile);
fputc('/', g_state.outputfile);
g_state.ulstate = END_STATE;
break;
case '\\':
nextch = fgetc(g_state.inputfile);
if (nextch == '"')
{
three = fgetc(g_state.inputfile);
if (three == '"')
{
fputc(ch, g_state.outputfile);
fputc('"', g_state.outputfile);
fputc('"', g_state.outputfile);
g_state.ulstate = NO_COMMENT_STATE;
}
else
{
fputc(ch, g_state.outputfile);
fputc(nextch, g_state.outputfile);
fputc(three, g_state.outputfile);
}
}
else
{
fputc(ch, g_state.outputfile);
fputc(nextch, g_state.outputfile);
}
break;
case '\n':
if (g_str_pre_state == NO_COMMENT_STATE)
{
fputc(ch, g_state.outputfile);
g_state.ulstate = NO_COMMENT_STATE;
}
else if (g_str_pre_state == CPP_COMMENT_STATE)
{
fputc('*', g_state.outputfile);
fputc('/', g_state.outputfile);
fputc(ch, g_state.outputfile);
g_state.ulstate = NO_COMMENT_STATE;
}
else
{
fputc(ch, g_state.outputfile);
g_state.ulstate = C_COMMENT_STATE;
}
break;
default:
fputc(ch, g_state.outputfile);
break;
}
}
主函数cctool.cpp
#include"ConvertComment.h"
#pragma warning (disable :4996)
int main()
{
FILE *fpIn = fopen("./cctdoc/input.c","r");
if(NULL == fpIn)
{
cout<<"Open input.c error."<<endl;
return OPEN_ERROR;
}
FILE *fpOut = fopen("./cctdoc/output.c","w");
if(NULL == fpOut)
{
cout<<"Open output.c errror."<<endl;
// printf("Open output.c Error.\n");
fclose(fpIn);
return OPEN_ERROR;
}
ConvertComment(fpIn,fpOut); //cheng funtion
fclose(fpIn);
fclose(fpOut);
printf("Convert complited\n");
return OK ;
}
测试文件放在项目目录的 ccdoc中 分别为input.c 与 output.c
input.c
//123
int main()
{
return 0;
}
//123456
/* 789 */
//456
//每个区由若干个内存块组成
//每个区由若干个内存块组成,//每个块是4096个字节
//int i = 0;*/
//*//*int i = 0;
// /**/ int i = 0;
/* int i = 0;
*//*
*/
/* int i = 0;
// */int j = 0;
/*
//每个区由若干个内存块组成,每个块是4096个字节
//每个块的第0个整数指向下个区
//所以是单链表结构
//所以每个区只有4092个字节存放真正的数据
*/
/* int i = 0;*//*int j = 0;
*/
/*
*//*
*/int i =0;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 5
"abcdefghijklmn~~~~!!!!!!!!"
/////abc
////bcd
/////////////xyz
///edf
/////////////6/2=3
char *str = "hello //comment convert.";
//char *str = "hello //comment convert.";
/*char *str = "hello //comment convert.";*/
/*char *str = "hello //comment convert.;*/
char *str1 = "hello /* comment */ convert.";
char *str = "abc\"syz";
//char *str = "abc\"syz";
/*abc**/
//abc"xy//z"
//abc"xy*/z"
最终效果为output.c
/*123*/
int main()
{
return 0;
}
/*123456*/
/* 789 */
/*456*/
/*每个区由若干个内存块组成*/
/*每个区由若干个内存块组成, 每个块是4096个字节*/
/*int i = 0; */
/* int i = 0;*/
/* int i = 0;*/
/* int i = 0;
*//*
*/
/* int i = 0;
*/int j = 0;
/*
每个区由若干个内存块组成,每个块是4096个字节
每个块的第0个整数指向下个区
所以是单链表结构
所以每个区只有4092个字节存放真正的数据
*/
/* int i = 0;*//*int j = 0;
*/
/*
*//*
*/int i =0;
/* 5*/
"abcdefghijklmn~~~~!!!!!!!!"
/* abc*/
/* bcd*/
/* xyz*/
/*/edf*/
/* 6/2=3*/
char *str = "hello //comment convert.";
/*char *str = "hello //comment convert.";*/
/*char *str = "hello //comment convert.";*/
/*char *str = "hello //comment convert.;*/
char *str1 = "hello /* comment */ convert.";
char *str = "abc\"syz";
/*char *str = "abc\"syz";*/
/*abc**/
/*abc"xy//z"*/
/*abc"xy*/z"*/