在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*/


// 8.C注释本身不匹配

/* int i = 0;


//9.在引号“”之中的注释

    对于任何一个项目。我们应该将复杂化的项目简单化。我们一步一步的去完善我们的程序。首先从第一项慢慢添加各种情况的功能。考虑每步的准确性,然后在统一进行最后的测试。

代码可能有点长,但是基本的原理还是比较简单的。一步一步去做。就能够做出来的~

下面给出代码,有一些简单的注释,不难理解,无非就是一步一步完善而已:

#include <stdio.h>
#include <assert.h>
typedef enum Flag
{
	ANNOTATION_START = 0,//在注释之中
	ANNOTATION_END = 1//注释已经成对,在注释之外。
}Flag;

typedef enum State
{
	SUCCESS,    //转换成功
	FILE_ERROR,//文件出现错误
	MATCH_ERROR,    //注释出现匹配错误。
	OTHER_ERROR,    //其他错误
}State;
State AnnotationConrent(char firstCh,char secondCh)
{
	FILE *In = fopen("In.c","r");
	FILE *Out = fopen("Out.c","w");
	State ret;
	Flag tag =	ANNOTATION_END;
	if(NULL == In)
	{
		return FILE_ERROR;
	}
	if(NULL == Out)
	{
		fclose(In);
		return  FILE_ERROR;
	}

	//1.普通注释
	do{
		firstCh = fgetc(In);
		switch(firstCh)
		{ 
		case '"':
			{//9.在引号之中的注释
				char next;
				fputc(firstCh,Out);
				while('"' != (next = fgetc(In)))
				{
					fputc(next,Out);
				}
				fputc(next,Out);
				break;
			}
		case '/':
			{		
				secondCh = fgetc(In);
				//3.匹配问题
				if('/' == secondCh)
				{
					fputc(firstCh,Out);
					fputc(secondCh,Out);
					while('\n' != (firstCh = fgetc(In))&& (EOF != firstCh))
					{
						fputc(firstCh,Out);
					}
					fputc('\n',Out);
				}
				else if('*' == secondCh && ANNOTATION_END == tag)
				{	
					secondCh = '/';
					fputc(firstCh,Out);
					fputc(secondCh,Out);
					tag = ANNOTATION_START;
					ret = MATCH_ERROR;
				}
				else 
				{
					fputc(firstCh,Out);
					fputc(secondCh,Out);
				}
				break;
			}
		case'\n':
			{
				fputc('\n',Out);
				//5.多行注释情况。
				if(ANNOTATION_START == tag)
				{
					fputc('\n',Out);
					fputc('/',Out);
					fputc('/',Out);
				}
				break;
			}
		case '*':
			{
				char next;
				secondCh = fgetc(In);
				//6.连续注释/***/
				if('*' == secondCh)
				{
					fputc(firstCh,Out);
					fseek(In,-1,SEEK_CUR);
				}
				if('/' == secondCh)
				{
					next = fgetc(In);
					// 2.换行问题
					if(EOF == next)
					{
						firstCh = EOF;
					}
					else if('\n' != next)
					{//5.连续注释/**//**/
						fputc('\n',Out);
						fseek(In,-1,SEEK_CUR);
					}
					else if('\n' == next)
					{
						fputc('\n',Out);
					}
					tag = ANNOTATION_END;

					//8.注释错误
					ret = SUCCESS;
				}
				break;
			}
		default:
			{	
				fputc(firstCh,Out);
				break;
			}
		}
	}while(EOF != firstCh);
	if(ANNOTATION_START == tag)
	{ //注释错误
		ret =OTHER_ERROR;
	}
	fclose(In);
	fclose(Out);
	return ret;
}

int main()
{	
	char firstCh = 0;
	char secondCh =0;
	State Sta ;
	Sta = AnnotationConrent(firstCh,secondCh);
	if(SUCCESS == Sta)
	{
		printf("转换成功");
	}
	else if(FILE_ERROR == Sta)
	{
		printf("文件打开错误");
	}
	else if(MATCH_ERROR == Sta)
	{
		printf("注释匹配错误");
	}
	else if(OTHER_ERROR == Sta)
	{
		printf("其它错误");
	}
	return 0;
}

    在任何项目中,标准的命名规范更容易加强对于程序的易见性。

    OK,项目是慢慢看出来的。就这样。