[数据结构]c++注释转化为c语言注释

每个程序员的代码注释风格不同,为统一代码注释风格,有时需要将c++注释转化为c语言注释或者反之,人工修改速度太慢,且容易出错,要是有一个专门负责注释代码转化的程序,必定事半功倍!!

题目要求:


注释转化要求如下:

注释的嵌套情形很多,这里只是举例,你需要遵照C/C++语言的注释规则来编写代码,我不会仅测试这里的例子。
1、单行注释或没有嵌套,注释行直接转换,如:
     ①//123                             /* 123 */
     ②/* 123 */                       /* 123 */ 不变
     ③/*123
         */                                   保持原样
2、有嵌套的注释(一个注释中还有嵌套其他注释符号//,/* */)嵌套中多余的每个注释符号用两个空格代替。

如单行:
 ① //123 /*456 */                            /*123   456*/
 ②//123//456                                   /*123   456*/ 
 ③//123*//*456                               /*123     456*/
如跨行
    /*……..                                         /*……..
    //………                                        ……….
    // ……..                                         ……….
    */                                                    */

注意事项:

1、除以下两种情况的修改,源文件转换后不能有任何其它的修改:
 ①多余的注释符用空格代替
 ②//在注释开始替换为/* ,行尾增加*/
2、下面的3种情形无需转换
 
① /* 123 */ /* 456 */
 ②/* 123 */ /* 456
    */ 
 ③/* 123
     */ /* 456
      */
3、不需要考虑输入文件中不符合语法规则的注释

代码如下:

CommentConvert.cpp

#include<iostream>
using namespace std;

#define UL unsigned long

extern int CommentConvert(FILE *inputfile, FILE *outputfile);//引入外部函数

/*枚举:各种状态*/
typedef enum
{
	NO_COMMENT_STATE, //无注释状态
	C_COMMENT_STATE,  //c语言注释状态
	CPP_COMMENT_STATE,//c++注释状态
	STR_STATE,        //字符串状态
	END_STATE         //结束状态,终态--状态机停止
}STATE_ENUM;

/*结构体:状态机*/
typedef struct
{
	FILE *inputfile;
	FILE *outputfile;
	STATE_ENUM ulstate;
}STATE_MACHINE;

//
STATE_MACHINE g_state = {0};

///
/*各类事件*/
void EventPro(char ch);
void EventProAtNo(char ch);
void EventProAtC(char ch);
void EventProAtCpp(char ch);
void EventProAtStr(char ch);


int CommentConvert(FILE *inputfile, FILE *outputfile)
{
	if(inputfile==NULL || outputfile==NULL)
	{
		cout<<"input argument Invalid!"<<endl;
		return -1;
	}

	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 0;
}

void EventPro(char ch)//驱动模型:由某一状态触发某一事件
{
	switch(g_state.ulstate)
	{
	case NO_COMMENT_STATE:
		EventProAtNo(ch);
		break;
	case C_COMMENT_STATE:
		EventProAtC(ch);
		break;
	case CPP_COMMENT_STATE:
		EventProAtCpp(ch);
		break;
	case STR_STATE:
		EventProAtStr(ch);
		break;
	case END_STATE:
		break;
	}
}

/*初始状态开始:可能转化:c注释,c++注释,终态,字符串状态*/
void EventProAtNo(char ch)
{
	char nextch;
	switch(ch)
	{
	case '/':   // // /* 
		nextch = fgetc(g_state.inputfile);
		if(nextch == '/') // C++注释开始,按c注释打印
		{
			fputc('/',g_state.outputfile);
			fputc('*',g_state.outputfile);
			g_state.ulstate = CPP_COMMENT_STATE;
		}
		else if(nextch == '*') //C注释开始,原样打印
		{
			fputc(ch,g_state.outputfile);
			fputc(nextch,g_state.outputfile);
			g_state.ulstate = C_COMMENT_STATE;
		}
		else
		{}
		break;
	case '"'://字符串状态
		fputc(ch,g_state.outputfile);
		g_state.ulstate = STR_STATE;
		break;
	case EOF://终态
		g_state.ulstate = END_STATE;
		break;
	default:
		fputc(ch,g_state.outputfile);
		break;
	}
}
/*c注释状态:可能遇到:c注释结束-->终态 c注释(空格代替),c++注释(空格代替),字符串状态(中的注释不改变)*/
void EventProAtC(char ch)
{
	char nextch;
	switch(ch)
	{
	case '*':
		nextch = fgetc(g_state.inputfile);
		if(nextch == '/')//c语言注释结束
		{
			fputc(ch,g_state.outputfile);
			fputc(nextch,g_state.outputfile);
			g_state.ulstate = NO_COMMENT_STATE;
		}
		else
		{
			fputc(ch,g_state.outputfile); //只有一个*号,将其打印
			fseek(g_state.inputfile,-1,1);//因为求nextch时调用fgetc,指针后移了一位,所以得将指针前移一位,否则会跳过一个字符
		}
		break;
	case '/':
		nextch = fgetc(g_state.inputfile);
		if(nextch == '/' || nextch == '*')//掺杂c++或者c语言注释,用两个空格代替
		{
			fputc(' ',g_state.outputfile);
			fputc(' ',g_state.outputfile);	
		}
		else
		{
			fputc(ch,g_state.outputfile); //只有一个/号,将其直接打印
			fseek(g_state.inputfile,-1,1);//因为求nextch时调用fgetc,指针后移了一位,所以得将指针前移一位,否则会跳过一个字符
		}
		break;
	case '"'://字符串状态
		fputc(ch,g_state.outputfile);
		g_state.ulstate = STR_STATE;
		break;
	default:
		fputc(ch,g_state.outputfile);
		break;
	}
}
//c++注释状态中可能包含:c注释(空格代替),c++注释(空格代替),字符串状态(中的注释不改变)
void EventProAtCpp(char ch)
{
	//123  /*123
	char nextch;
	switch(ch)
	{
	case EOF:
		fputc('*',g_state.outputfile);
		fputc('/',g_state.outputfile);
		g_state.ulstate = END_STATE;
		break;
	case '*':
		nextch = fgetc(g_state.inputfile);
		if(nextch == '/')//掺杂其他注释,用两个空格代替
		{
			fputc(' ',g_state.outputfile);
			fputc(' ',g_state.outputfile);	
		}
		else
		{
			fputc(ch,g_state.outputfile);
			fseek(g_state.inputfile,-1,1);
		}
		break;
	case '/':
		nextch = fgetc(g_state.inputfile);
		if(nextch == '*')//掺杂c语言注释,用两个空格代替
		{
			fputc(' ',g_state.outputfile);
			fputc(' ',g_state.outputfile);	
		}
		else if(nextch == '/')//掺杂c++注释,用两个空格代替
		{
			fputc(' ',g_state.outputfile);
			fputc(' ',g_state.outputfile);	
		}
		else
		{
			fputc(ch,g_state.outputfile);
			fseek(g_state.inputfile,-1,1);
		}
		break;
	case '"'://字符串状态
		fputc(ch,g_state.outputfile);
		g_state.ulstate = STR_STATE;
		break;
	default:
		fputc(ch,g_state.outputfile);
		break;
	}
}
/*字符串状态:c注释(原样输出)c++注释(原样输出),终态*/
void EventProAtStr(char ch)
{
	char nextch;
	switch(ch)
	{
	case '\0':
		nextch = fgetc(g_state.inputfile);
		if(nextch == '"')
		{
			fputc(ch,g_state.outputfile);
			fputc(nextch,g_state.outputfile);
			g_state.ulstate = NO_COMMENT_STATE;
		}
		break;
	case EOF:
		g_state.ulstate = END_STATE;
	default:
		fputc(ch,g_state.outputfile);
		break;
	}
}
main.cpp

#include<iostream>
using namespace std;

extern int CommentConvert(FILE *inputfile, FILE *outputfile);

int main()
{
	FILE *fpIn = NULL;  //inputfile
	FILE *fpOut = NULL; //outputfile

	fpIn = fopen("input.c","r");
	if(NULL == fpIn)
	{
		cout<<"Open input file fail!"<<endl;
		return -1;
	}
	fpOut = fopen("output.c","w");
	if(NULL == fpOut)
	{
		cout<<"Open output file fail!"<<endl;
		return -1;
	}

	CommentConvert(fpIn,fpOut); //

	fclose(fpIn);
	fclose(fpOut);
	return 0;
}

测试用例如下

输入input.c:

//abc**def

//每个区由若干个内存块组成

//每个区由若干个内存块组成,//每个块是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

char *s = "abcdefghijklmn//~~/*~~*/!!!!!!!!";

output.c:

/*abc**def*/

/*每个区由若干个内存块组成*/

/*每个区由若干个内存块组成*/

/*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*/
char *s = "abcdefghijklmn//~~/*~~*/!!!!!!!!";


有关状态机的概念 点击此处点击打开链接





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值