注释转换

  • c注释-->c++注释,将.c风格的注释转换成.cpp风格
  • 采用有限状态机的方式实现
  • 设置四种状态,c状态,c++状态,空状态,结束状态,主要关注四种状态转换的条件,状态转换如下:
//test.cpp

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<assert.h>
#include"CommentConvert.h"
using namespace std;

int main()
{
	FILE *pRead=fopen("input.cpp","r");
	if (pRead == NULL)
	{
		perror("open file for read");//将上一个函数发生错误的原因输出到标准设备(stderr)。参数 s 所指的字符串会先打印出,后面再加上错误原因字符串
		exit(EXIT_FAILURE);//exit()函数先处理完上面你列出的许多后事,最后将它的参数返回给操作系统作为exit status。所以从exit函数本身执行来说并没有什么不同。不同的是操作系统对这个exit status的解释。一般0表示程序寿终正寝,1表示死于非命。
	}

	FILE *pWrite = fopen("output.cpp", "w");
	if (pWrite == NULL)
	{
		fclose(pRead);//写的不存在,需要把读的关掉。那不相当于关了两次?,应该出现异常执行不到后面的fclose
		perror("open file for write");
		exit(EXIT_FAILURE);
	}

	_StartConvert(pRead, pWrite);

	fclose(pRead);
	fclose(pWrite);

	system("pause");

	return 0;
}

 

//CommentConvert.h

# pragma once
#include<iostream>
using namespace std;

void _StartConvert(FILE* fin, FILE* fout);
void OnNullState(FILE* fin, FILE* fout);
void OnCState(FILE* fin, FILE* fout);
void OnCppState(FILE* fin, FILE* fout);

 

//CommentConvert.cpp

#include<iostream>
#include<assert.h>
#include"CommentConvert.h"
using namespace std;

enum State
{
	NULL_STATE,//空状态
	C_STATE,//C状态
	CPP_STATE,//C++状态
	END_STATE,//结束
};
enum State state = NULL_STATE;

void OnNullState(FILE* fin, FILE* fout)
{
	char first = fgetc(fin);
	if (first == '/')
	{
		char second = fgetc(fin);
		if (second == '/')
		{
			//fputs("//", fout);
			state = CPP_STATE;
		}
		else if (second == '*')
		{
			//fputs("//", fout);
			state = C_STATE;
		}
		fputs("//", fout);
	}
	//else if (state == '\n')
	//{
	//	fputc(first, fout);
	//	state = NULL_STATE;
	//}
	else if (state == EOF)
	{
		fputc(first, fout);
		state = END_STATE;
	}
	else
	{
		fputc(first, fout);
	}
}

void OnCState(FILE* fin, FILE* fout)
{
	char first = fgetc(fin);
	if (first == '*')
	{
		char second = fgetc(fin);
		if (second == '/')
		{
			state = NULL_STATE;
			char third = fgetc(fin);
			if (third != '\n')
			{
				fputs("\n", fout);//如果/后边的字符不是回车,需要写进去回车,然后再把独到的字符放回。//考虑到连续两个c注释的问题 比如  /* int a = 1; */  /* int b = 1;*/   将它们放在两行
				ungetc(third, fin);
			}
			else
			{
				fputc(third, fout);
			}
		}
		else
		{
			fputc(first, fout);
			//如果遇到*,但是后边不是/,把*放进去,*后边的字符放回,比如,/***/,进入c状态以后,
			//遇到*,后边的字符也是*,如果把两个*都写进去,后边就只剩下/,就不能找到c状态结束的标志,
			//所以,需要把第二个字符原样写回。//接下来执行哪儿,跳不到51呀
			ungetc(second, fin);
		}
	}
	else if (state == '\n')//多行注释
	{
		fputc(first, fout);
		//state = NULL_STATE;
		fputs("//", fout);//?????????????????
	}
	/*else if (state == EOF)
	{
		fputc(first, fout);
		state = END_STATE;
	}*/
	else
	{
		fputc(first, fout);
	}
}

void OnCppState(FILE* fin, FILE* fout)
{
	char first = fgetc(fin);
	if (state == '\n')
	{
		fputc(first, fout);
		state = NULL_STATE;
	}
	else if (state == EOF)
	{
		fputc(first, fout);
		state = END_STATE;
	}
	else 
	{
		fputc(first, fout);   //别忘了这个else,不然CPP_STATE中的正常字符都不会输出。考虑特殊情况,也别忘了正常情况。
	}

}

void _StartConvert(FILE *fin, FILE *fout)
{
	while (1)
	{
		switch (state)
		{
		case NULL_STATE:OnNullState(fin, fout); break;
		case C_STATE:   OnCState(fin, fout); break;
		case CPP_STATE: OnCppState(fin, fout); break;
		case END_STATE:  break;
		default:assert(false); break;
		}
	}
}

 

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值