注释转换

本文介绍了一个用于将C语言源代码中的多行注释转换为单行注释的程序。该程序通过状态机的方式处理输入文件,并将转换后的代码输出到另一个文件中。解决了包括换行、连续注释及C++风格注释等多种复杂场景。
#include<errno.h>
#include<stdio.h>
#include<string.h>

#pragma warning (disable:4996)

enum STATE{
	SUCCESS = 0,		// 成功
	FILE_ERROR = 1,		// 文件错误
	NO_MATCH = 2,		// 不匹配
	OTHER_ERROR = 3,	// 其他错误
};

enum TAG
{
	TAG_NONE,			// 无效标志
	TAG_BEGIN,			// 开始标志
	TAG_END,			// 结束标志
};

typedef enum STATE STATE;
typedef enum TAG TAG;


STATE DealState(FILE* fIn, FILE* fOut)
{
	TAG tag = TAG_END;
	char first, second;

	do{
		first = fgetc(fIn);

		switch(first)
		{
		case '/': 
			second = fgetc(fIn);
			if (second == '*') // /* -> //
			{
				//
				// 3.匹配问题--通过tag标志识别
				//
				if (tag == TAG_END)
				{
					fputc('/', fOut);
					fputc('/', fOut);
					tag = TAG_BEGIN;
				}
			}
			else if (second == '/')
			{
				char next;
				//
				// 7.C++注释问题--读完当前行
				//
				fputc('/', fOut);
				fputc('/', fOut);
				do {
					next = fgetc(fIn);
					if (next == EOF)
						break;

					fputc(next, fOut);
				}while(next != '\n');
			}
			else
			{
				fputc(first, fOut);
				fputc(second, fOut);
			}

			break;
		case '\n':
			//
			// 4.多行注释问题--如果是C++注释,则在行首添加//
			//
			fputc('\n', fOut);
			if (tag == TAG_BEGIN)
			{
				fputc('/', fOut);
				fputc('/', fOut); 
			}

			break;
		case '*':
			second = fgetc(fIn); 
			if (second == '/')
			{
				// 检查标志
				if (tag == TAG_BEGIN)
				{
					char next;
					tag = TAG_END;

					// 2.换行问题
					// 5.连续注释问题
					next = fgetc(fIn);
					if (next == EOF)
					{
						break;
					}
					else if (next != '\n')
					{
						fputc('\n', fOut);
						fseek(fIn, -1, SEEK_CUR);
					}
					else
					{
						fputc(next, fOut);
					}
				}
			}
			else if(second == '*')
			{
				// 6.连续的**/收尾
				fputc(first, fOut);
				fseek(fIn, -1, SEEK_CUR);
			}
			break;
		default:
			if (first != EOF)
			{
				fputc(first, fOut);
			}
			break;
		}
	}while (first != EOF);

	if (tag != TAG_END)
	{
		return NO_MATCH;
	}
	else
	{
		return SUCCESS;
	}
}

// 注释转换
STATE AnnotationConvert (const char* inFileName, const char* outFileName)
{
	STATE ret;
	FILE* fIn = fopen (inFileName, "r");
	FILE* fOut = fopen (outFileName, "w");

	if (fIn == 0)
	{
		return FILE_ERROR;
	}

	if (fOut == 0)
	{
		fclose(fIn);

		return FILE_ERROR;
	}

	//
	// 处理状态机
	// 
	ret = DealState (fIn, fOut);

	fclose(fIn);
	fclose(fOut);

	return ret;
}

void StartConvert ()
{
	const char* inFileName = "input.c";
	const char* outFileName = "output.c";

	STATE s = AnnotationConvert(inFileName, outFileName);

	if (s == SUCCESS) {
		printf("Convert Success\n");
	}
	else if (s == FILE_ERROR)
	{
		printf("File Error: %d\n", errno);
	}
	else if (s == NO_MATCH)
	{
		printf("No Match\n");
	}
	else
	{
		printf("Other Error\n");
	}
}

处理的问题

// 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;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值