用C语言实现 C到C++的注释转换



注释转换用于文件中,将文件里面的C风格的注释,转换为CPP风格的注释。(C风格的注释有不能嵌套的缺陷

还会出现一些换行问题、匹配问题、多行注视问题、连续注释问题、连续的**问题等等。。。
C风格注释:/* int i=0; */ 
CPP风格注释:// int i=0;

由上图可知:C语言注释转换主要分为四个状态:NUL_STATE(空状态)、C_STATE(C注释状态)、CPP_STATE(C++注释状态)和END_STATE(结束状态);

1.当为NUL_STATE状态时,遇到特定标记时进行状态转换,它有可能保持NUL_STATE状态,可能进入C_STATE状态,可能进入CPP_STATE状态,也可能进入结束状态。(橙色箭头)

2.当为CPP_STATE状态时,遇到特定标记时进行状态转换,它有可能保持CPP_STATE(C++状态),可能进入NUL_STATE(空状态),也可能进入END_STATE(结束状态)。(红色箭头)

3.当为C_STATE状态时,遇到特定标记时进行状态转换,它有可能保持C_STATE(C状态),可能进入NUL_STATE(空状态)。(蓝色箭头)


4.当为结束状态时,转换束。

*重要的是要分清每个状态结束的条件以及各个状态相互转换的边界条件,然后对其作具体情况的分析处理。


CommentConvert.h

#define _CRT_SECURE_NO_WARNINGS 1
#ifndef __COMMENT_CONVERT_H__//为了防止头文件的重引用
#define __COMMENT_CONVERT_H_
#include <stdio.h>
#include <stdlib.h>

enum STATE//枚举下面4种状态
{
	END_STATE,//结束状态
	NUL_STATE,//空状态
	C_STATE,//C注释状态
	CPP_STATE//C++注释状态
};

void DoNulState(FILE*pfIn, FILE*pfOut, enum STATE* s);//无注释时的处理
void DoCState(FILE*pfIn, FILE*pfOut, enum STATE* s);//c注释时的处理
void DoCppState(FILE*pfIn, FILE*pfOut, enum STATE* s);//cpp注释时的处理

#endif //__COMMENT_CONVERT_H__


CommentConvert.c

#include "CommentConvert.h"

void DoNulState(FILE*pfIn, FILE*pfOut, enum STATE* s)//无注释时的处理
{
	int first = 0;
	first = fgetc(pfIn);
	switch (first)
	{
	case '/'://如果取出的字符为'/',有可能进入以下状态
	{
				int second = 0;//取出第二字符以确定状态是否需要转换
				second = fgetc(pfIn);
				switch (second)
				{
				case '/':   //处理CPP情况,如果第二个字符是'/',进入C++状态
				{
								fputc(first, pfOut);
								fputc(second, pfOut);
								*s = CPP_STATE;//回到CPP的状态
								break;
				}
					
				case '*':  // 处理C状况,如果第二个字符是‘*’,进入C状态
				{
							   fputc('/', pfOut);
							   fputc('/', pfOut);
							   *s = C_STATE;//回到C的状态
							   break;
				}
				
				default://如果是其他字符,保持空状态
					fputc(first, pfOut);
					fputc(second, pfOut);
					break;
				}
	}
		break;
	case EOF://如果到达文件结尾,进入结束状态
		fputc(first, pfOut);
		*s = END_STATE;
		break;
	default://如果第一个字符是非'/'字符则进行空状态处理
		fputc(first, pfOut);
		break;
	}
}

void DoCState(FILE*pfIn, FILE*pfOut, enum STATE* s)
{
	int first = 0;
	first = fgetc(pfIn);
	switch (first)
	{
	case '*'://如果取出的第一个字符为'*',C状态可能要结束
	{
				int second = 0;
				second = fgetc(pfIn);
				switch (second)
				{
				
					case '/'://一般情况:/* int i = 0; */  
						fputc('\n', pfOut);
						*s = NUL_STATE;
						break;
					case'*'://second中,如果取出的第二个字符为'*'说明C状态没有结束
						ungetc(second, pfIn);//如果接下来仍然是'*',则将'*'返回给pfIn中,把取出的第二个字符送回,以便下次读取
						fputc(second, pfOut);
						break;
					default://如果是其他字符,字符进行C状态处理
						fputc(first, pfOut);
						fputc(second, pfOut);
						break;
				}
	}
		break;

	case '\n'://进行C状态的多行注释处理
	{
				 fputc(first, pfOut);//连续注释时,在每行的开头加上CPP注释风格
				 fputc('/', pfOut);
				 fputc('/', pfOut);
	} 
		break;
	default://如果是其他字符,字符进行C状态处理
		fputc(first, pfOut);
		break;
	}
}

void DoCppState(FILE*pfIn, FILE*pfOut, enum STATE* s)//CPP的注释处理
{
	int first = 0;
	first = fgetc(pfIn);
	switch (first)
	{
	case '\n'://如果取出的第一个字符为'\n'说明C++注释转换结束,进入空状态
		fputc('\n', pfOut);
		*s = NUL_STATE;
		break;
	case EOF://如果到达文件结尾,进入结束状态
		*s = END_STATE;
		break;
	default://如果第一个字符是非'\n',说明C++状态没有结束,字符进行C++状态处理
		putc(first, pfOut);
		break;
	}
}


test.c

#include "CommentConvert.h"
void CommentConvert(FILE*pfIn, FILE*pfOut)
{
	enum STATE s = NUL_STATE;
	while (s != END_STATE)
	{
		switch (s)
		{
		case NUL_STATE://空状态
			DoNulState(pfIn, pfOut, &s);//传递状态以及文件
			break;
		case C_STATE://C状态
			DoCState(pfIn, pfOut, &s);
			break;
		case CPP_STATE://C++状态
			DoCppState(pfIn, pfOut, &s);
			break;
		default:
			break;
		}
	}
}
void test()
{
	FILE *pfIn = NULL;
	FILE *pfOut = NULL;
	pfIn = fopen("input.c", "r");//以只读的形式打开
	if (pfIn == NULL)
	{
		perror("use fopen of Input");
		exit(EXIT_FAILURE);
	}
	pfOut = fopen("output.c", "w");
	if (pfOut == NULL)
	{
		perror("use fopen of pfOut");
		fclose(pfIn);
		exit(EXIT_FAILURE);
	}
	CommentConvert(pfIn, pfOut);
	fclose(pfIn);
	fclose(pfOut);
}
int main()
{
	test();
	system("pause");
	return 0;
}


运行结果(也指明了C注释的一些问题)



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值