小项目-C语言注释转化为C++注释

  今天我们来实现一个小项目:C语言注释转化为C++注释

      C语言注释/**/ 可以注释多行
    C++注释//    只能注释一行
    看到这个项目我们首先应该想到的是注释转化应该有哪几种状态,在我的代码设置中有4种状态:
    NUL-STATE:空状态,初始状态为空状态;
    C-STATE:C语言状态;
    CPP_STATE:C++状态
    END_STATE:结束状态
    
enum STATE
{
	NUL_STATE,
	C_STATE,
	CPP_STATE,
	END_STATE
};



    在这四种情况下都会遇到什仫情况呢?下面我们来看一张详解注释转换的图片:微笑
    
          在这张图中我们可以清楚的看到每种情况转化过程遇到的特殊情况,接下来就是如何去处理这个项目了。在我的代码中用的是文件的方式,首先创建一个input.c存放初始未转换的C代码,然后就是创建一个output.c来存放注释转化之后的代码啦!下面给出初始未转化的C代码,也就是测试代码:
       
// 1.一般情况
/* 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*/

       接下来就是如何去实现这个过程了,这个项目有1个头文件CommentConvert.h,两个.c文件CommentConvert.c和text.c,我们将初始状态置为NUL_STATE状态,通过出现不同的情况分别进入C_STATE状态,CPP_STATE状态和END_STATE状态下面我们就不同的情况进行具体分析:
      在NUL_STATE状态中如果出现'/*'则将'//'写入output.c里面去并进入C_STATE状态;如果出现'//'则直接输出'//'并进入CPP_STATE状态;如果出现EOF则将状态置为END_STATE状态(结束状态);如果都不是说明是普通字符则直接输出就可以了.
      在C_STATE状态中如果出现*/由上面的测试用例可知此时存在三种情况:
      情况一:一般情况*/后面没有任何元素则直接忽视掉*/就可以了;
      情况二:连续的注释问题/**//**/
      情况三:连续的/***/问题
      情况四:*/后面出现换行和不换行
      情况一,情况二和情况四如何去解决呢?我们可以设置第三个变量取出*/之后的字符通过判断,如果第三个变量是'/'则属于情况二,此时只需要我们在output.c再放入一个'/'并将状态置为NUL_STATE状态就可以了;
     如果取出的第二个字符是'*'那仫就属于情况三了,此时我们需要将读到的第一个字符也就是'*'写入,如果第三个字符是'/'则进入空状态继续判断下一个;
      如果取出的第三个字符不是'\n'呢?也就是我们测试用例中的情况二,如果不是'\n'我们将'\n'写入,因为如果遇到'*/'说明C注释已经结束了,此时只需要将后面的字符换行就可以了;
       如果取出的不是'*/'而是'\n'呢?此时就属于C_STATE状态的多行注释问题了 ,此时我们只需要将'\n'写入output.c文件中并输出两个'/'就可以了,因为在多行C注释转化中如果我们将第一个出现的'/*'转化为'//'那仫之后的每一行我们都需要添加注释'//';如果出现EOF则和空状态的处理方式一致;如果是其他字符则直接输出;
     在CPP_STATE状态中情况比较简单只有'\n','EOF'的情况,如果出现'\n'则将'\n'写入output.c文件中,并将状态置为空状态;如果出现EOF和上述处理方法一样;如果是其他字符则直接输出;
     好了分析了这仫久让我们直接上代码吧!微笑
    text.c
    
#define _CRT_SECURE_NO_WARNINGS
#include"CommentConvert.h"
int main()
{
	FILE *pfread=NULL;
	FILE *pfwrite=NULL;
	printf("转化开始\n");
	pfread=fopen(INPUTFILENAME,"r");
	if(NULL == pfread)
	{
		perror("open file for read\n");
		exit(EXIT_FAILURE);
	}
	pfwrite=fopen(OUTPUTFILENAME,"w");
	if(NULL == pfwrite)
	{
		fclose(pfread);
		perror("open file for write\n");
		exit(EXIT_FAILURE);
	}
	CommentConvert(pfread,pfwrite);
	printf("转化结束\n");
}


  CommentConvert.h
   
#ifndef __COMMENT_CONVERT_H    //防止重复引入
#define __COMMENT_CONVERT_H
#define INPUTFILENAME "input.c"
#define OUTPUTFILENAME "output.c"
#include<stdio.h>
#include<stdlib.h>
enum STATE
{
	NUL_STATE,
	C_STATE,
	CPP_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);
#endif


   CommentConvert.c
        
#include"CommentConvert.h"
enum STATE state=NUL_STATE;
int first=0;
int second =0;
int third=0;

void Do_NUL_State(FILE *pfread,FILE *pfwrite)
{
	first=fgetc(pfread);
	switch(first)
	{
	case '/':
		second=fgetc(pfread);
		if(second == '*')        //C注释转化为C++注释
		{
			fputc('/',pfwrite);
			fputc('/',pfwrite);
			state=C_STATE;
		}
		else if(second == '/')   //C++注释直接输出并进入C++模式
		{
			fputc(first,pfwrite);
			fputc(second,pfwrite);
			state=CPP_STATE;
		}
		else                    //是其他字符直接输出
		{
			fputc(first,pfwrite);
			fputc(second,pfwrite);
		}
		break;
	case EOF:                  //文件结束标志
		state=END_STATE;
		break;
	default :                 //不是注释的字符
		fputc(first,pfwrite);
		break;
	}
}

void Do_C_State(FILE *pfread,FILE *pfwrite)
{
	first=fgetc(pfread);
	switch(first)    
	{
	case '*':
		second=fgetc(pfread);
		switch(second)
		{
		case '*':                  //   6.连续的/***/问题
			third=fgetc(pfread);
		    fputc(first,pfwrite);
			if(third == '/')    
			{
				state=NUL_STATE;
			}
			break;
		case '/':
			third=fgetc(pfread);
			if(third != '\n')     //   /* int i = 0; */int j = 0;
			{
				fputc('\n',pfwrite);
			}
			if(third == '/')       //5.连续的注释问题/**//**/
			{
				ungetc('/',pfread);
				state=NUL_STATE;
				break;
			}
			fputc(third,pfwrite);   //   /* int i = 0; */ \n int j = 0;
			state=NUL_STATE; 
			break;
		default:                   //不是注释的字符
			fputc(first,pfwrite);
			fputc(second,pfwrite);
			break;
		}
		break;
	case '\n':                   //4.C注释中的多行注释
		fputc('\n',pfwrite);
		fputc('/',pfwrite);
		fputc('/',pfwrite);
		break;
	case EOF:                 //文件结束标志
		state=END_STATE;
		break;
	default:                 //不是注释的字符
		fputc(first,pfwrite);
		break;
	}
}

void Do_CPP_State(FILE *pfread,FILE *pfwrite)
{
	first=fgetc(pfread);
	switch(first)
	{
	case '\n':
		fputc(first,pfwrite);
		state=NUL_STATE;
		break;
	case EOF:
		state=END_STATE;
		break;
	default :     //7.不是注释的字符
		fputc(first,pfwrite);
		break;
	}
}

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 END_STATE:
			break;
		}
	}
}



        在这里我们的代码就实现完成了,那仫是不是能够达到我们注释转化的目的呢?让我们打开output.c,结果如下:
       
// 1.一般情况
// 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*/


      在最后以一句话勉励自己:只要你想,只要你做,没有什仫困难是不能克服的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值