[置顶] 用C语言写的注释转换

       学过C语言的都知道,在C语言中注释是用/*和*/表示的,/*与*/之间的内容就是注释内容。当然用//也可以作为注释,//后面的内容就是注释的内容,不过这种注释通常用于C++之中,今天就用C语言来写个小程序,是关于C语言中的注释转换,如何将C语言中的注释风格转化为C++中的注释风格。

用图来表示就是:(将input.c中的内容通过注释转化写入到Output.c中)

[置顶] 用C语言写的注释转换_第1张图片

即将/*???*/转化为//,虽然看上去只是一个简单的替换,但是其中还是包含有很多的内容的。换句话说,这样一个小项目还是有几个需要注意的地方。

在我看来其中有以下几个需要注意的地方:
 1. 一般情况
/* int i = 0; */

 2. 换行问题
/* int i = 0; */int j = 0;
/* int i = 0; */
int j = 0;

 3. 匹配问题
/* int i = 0; /*xxxxxxxx*/

 4. 多行注释问题
/*
int i = 0;
int j = 0;
int k = 0;
*/int k = 0;

5. 连续注释问题
/**//**/

6. 连续的**/问题
/***/

7. C++注释问题
 /*xxxxxxxxxxxxxxxxxxxx*/

这么多种情况我们如何去表示所有情况呢?如果用if--else语句是不是过于麻烦了呢?于是我们可以采用以下的思路,就是列出四种状态,分别是1--空状态(没有状态,就是普通的有效的代码),2--C语言注释状态(遇到/*进入C语言的注释状态),3--C++注释状态(即遇到//后面这一行的都属于C++注释状态),4--结束状态(遇到文件结束标志EOF后产生的状态),这些状态之间遇到特定的条件都可以发生注释转化。

我们可以用图来更形象的表示:

[置顶] 用C语言写的注释转换_第2张图片

NULL--普通状态      C语言--C语言注释状态    Cpp--C++的注释状态   end--遇到EOF结束了

(注:特殊条件下C语言到普通状态也可以用/n来达到,可以不讨论这种情况)


下面是代码:

首先是头文件:Comment_Convert.h

#ifndef __COMMENT_CONVERT_H__
#define __COMMENT_CONVERT_H__
#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<stdlib.h>

typedef enum  Convert_State                         //用枚举定义四种状态
{
	NULL_STATE,
	C_STATE,
	CPP_STATE,
	END_STATE
}Now_State;
#define FILEINPUTNAME "Input.c"                     //从Input.c之中去读我们的内容
#define FILEOUTOUTNAME "Output.c"                   //将注释转化好的内容写入Output.c之中

void Comment_Convert();                             
void Convert_Main(FILE * read, FILE * write);
void Do_NULL_State(FILE * read, FILE * write);
void Do_Cpp_State(FILE * read, FILE * write);
void Do_C_State(FILE * read, FILE * write);
#endif // !__COMMENT_CONVERT_H__

接下来是具体函数的实现:新创建一个源文件 CommentConvert.c,把这些内容写到CommentConvert.c文件中,
#include "CommentConvert.h"
Now_State State;
void Do_C_State(FILE * read, FILE * write)                //主要功能是实现在C状态下的读写操作
{
	int first = fgetc(read);
 	int second = 0;
	switch (first)
	{
	case '*':
		second = fgetc(read);
		if (second == '/')                                      //一般情况,后面的*/直接舍弃
		{
			int ch = fgetc(read);
			if (ch != ' ')
			{
				fputc('\n', write);             //多行注释问题以及连续注释问题解决方法
				ungetc(ch, read);
			}
			State = NULL_STATE;
		}
		else
		{
			fputc(first, write);                            //连续的**/问题
			ungetc(second, read);
		}
		break;
	case '/':                                                       // 匹配问题解决方法 
		second = fgetc(read);
		if (second == '*')
		{
			fputc(first, write);
			fputc(second, write);
		}
		else
		{
			fputc(first, write);
		}
		break;
	case '\n':
		fputc(first, write);                                   //换行问题解决方法
		fputc('/', write);
		fputc('/', write);
		break;
	case EOF:
		fputc(first, write);
		State = END_STATE;
		break;
	default:
		fputc(first, write);
		break;
	}
}

void Do_Cpp_State(FILE * read, FILE * write)                       //主要功能是实现C++状态下的读写操作
{
	int first = 0;
	int second = 0;
	first = fgetc(read);
	switch (first)
	{
	case '\n':                                             //遇到换行直接改为普通状态即可
		fputc('\n', write);                         
		State = NULL_STATE;
		break;
	case EOF:
		fputc(first, write);
		State = END_STATE;
		break;
	default:
		fputc(first, write);
		break;
	}
}

void Do_NULL_State(FILE * read, FILE * write)                  //主要功能是实现普通状态下的读写操作
{
	int first = fgetc(read);
	int second = 0;
	switch (first)
	{
	case '/':                                              //普通状态下遇到'/'之后的内容需要分情况
		second = fgetc(read);
		if (second == '*')
		{
			fputc(first, write);
			fputc('/', write);
			State = C_STATE;
		}
		else if (second == '/')
		{
			fputc(first, write);
			fputc(second, write);
			State = CPP_STATE;
		}
		else
		{
			fputc(first, write);
			fputc(second, write);
		}
		break;
	case EOF:
		fputc(first, write);
		State = END_STATE;
		break;
	default:
		fputc(first, write);
		break;
	}
}

void Comment_Convert()                                        //文件的打开以及异常的捕捉
{
	FILE * Pread = NULL;
	FILE * Pwrite = NULL;
	Pread = fopen(FILEINPUTNAME, "r");
	if (NULL == Pread)
	{
		perror("打开文件失败!");
		exit(EXIT_FAILURE);
	}
	Pwrite = fopen(FILEOUTOUTNAME, "w");
	if (NULL == Pwrite)
	{
		fclose(Pread);
		perror("打开文件失败!");
		exit(EXIT_FAILURE);
	}
	Convert_Main(Pread, Pwrite);
	fclose(Pread);
	fclose(Pwrite);
}

void Convert_Main(FILE * read, FILE * write)                   //转换函数
{
	State = NULL_STATE;
	while (State != END_STATE)
	{
		switch (State)
		{
		case NULL_STATE:
			Do_NULL_State(read, write);
			break;
		case C_STATE:
			Do_C_State(read, write);
			break;
		case CPP_STATE:
			Do_Cpp_State(read, write);
		default:
			break;
		}
	}
}

接下来就是测试文件:test.c

#include<stdio.h>
void Annotation_Convert()                              //转化函数
{
	Comment_Convert();
}

int main()
{
	Annotation_Convert();                         
	return 0;
}

将程序运行起来之后:(测试结果如下:)

要读的文件(Input.c)

[置顶] 用C语言写的注释转换_第3张图片

输出的文件内容:(Output.c)

[置顶] 用C语言写的注释转换_第4张图片

注释转化就完成了,不过转换之后比原来的内容多了几个换行。

你可能感兴趣的:([置顶] 用C语言写的注释转换)