c语言转HX,c语言小项目----注释转换

这篇博客,我将整理关于注释转换的知识,首先,得知道,注释转换包括,c语言注释转

换成c++注释,和c++注释转换成c语言注释。

c语言注释的风格:/*这是c语言注释*/

c++语言注释风格://这是c++注释风格

下面,我主要分析将所有的注释转换成c++注释,即就是c语言注释转换成c++注释。

这样的转换会存在以下多种情况:

1.一般情况:/* int i = 0;*/转换后就是//int i = 0;

2.换行问题:

/* int i = 0; */int j = 0;

/* int i = 0; */

int j = 0;

3.匹配问题:

/*int i = 0;/*xxxxx*/转换后就是//int i = 0;/*xxxxx

4.多行注释问题:

/*

int i=0;

int j = 0;

int k = 0;

*/int k = 0;

转换后就是:

//

//int i = 0;

//int j = 0;

//int k = 0;

//

int k = 0;

5.连续注释问题:

/**//**/

转换后就是://

//

6.连续的**/问题:

/***/

转换后就是://*

7.C++注释问题:

// /*xxxxxxxxxxxx*/

转换后还是// /*xxxxxxxxxxxx*/

8.字符串里的注释:

"/*helloyaoyao*/"

转换后还是:"/*helloyaoyao*/"

由于情况比较大,所以,我们运用一个叫做有限状态机的东西~~

我们主要的工作是将input.c里的内容通过注释转换写进output.c里。

有限状态机:

有限状态机FSM是软件上常用的一种处理⽅法,它把复杂的控制逻辑分解成有限个稳定

状态,在每个状态上进行处理。有限状态机是闭环系统,可以用有限的状态,处理无穷

的事务。

关于c注释到c++注释的状态转换图如下:

0818b9ca8b590ca3270a3433284dd417.png

c状态是不会到结束状态的。

下边来看源码(便于读者理解,所以代码中写的注释可能比较通俗易懂一点,也不是特

别专业):

//test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include"commentconvert.h"

int main()

{

FILE *pfRead = NULL;

FILE *pfWrite = NULL;

printf("注释开始\n");

pfRead = fopen(INPUTNAME, "r");

if (NULL == pfRead)

{

perror("open file for read");

exit(EXIT_FAILURE);

}

pfWrite = fopen(OUTPUTNAME, "w");

if (NULL == pfWrite)

{

fclose(pfRead);

perror("open file for write");

exit(EXIT_FAILURE);

}

commentcovert(pfRead, pfWrite);

printf("注释结束\n");

system("pause");

return 0;

}

//commentconvert.h

#ifndef __COMMENTCOVERT_H__

#define __COMMENTCOVERT_H__

#define INPUTNAME "input.c"

#define OUTPUTNAME "output.c"

#include

#include

enum STATE

{

NUL_STATE,

C_STATE,

CPP_STATE,

END_STATE,

STR_STATE

};

void commentcovert(FILE *pfRead, FILE *pfWrite);

void Do_NUL_STATE(FILE *pfRead, FILE *pfWrite);

void Do_C_STATE(FILE *pfRead, FILE *pfWrite);

void Do_CPP_STATE(FILE *pfRead, FILE *pfWrite);

void Do_STR_STATE(FILE *pfRead, FILE *pfWrite);

#endif//

//commentconvert.c

#include"commentconvert.h"

enum STATE state = NUL_STATE;

void commentcovert(FILE *pfRead, FILE *pfWrite)

{

while (state != END_STATE)

{

switch(state)

{

case NUL_STATE:

Do_NUL_STATE(pfRead, pfWrite);

break;

case C_STATE:

Do_C_STATE(pfRead, pfWrite);

break;

case CPP_STATE:

Do_CPP_STATE(pfRead, pfWrite);

break;

case STR_STATE:

Do_STR_STATE(pfRead, pfWrite);

break;

case END_STATE:

break;

}

}

}

void Do_NUL_STATE(FILE *pfRead, FILE *pfWrite)

{

int first = 0;

int second = 0;

first = fgetc(pfRead);

switch (first)

{

case '/':

second = fgetc(pfRead);

if (second == '/')

{

fputc('/', pfWrite);

fputc('/', pfWrite);

state = CPP_STATE; //在无状态下遇到//直接将//写进去,并进入cpp状态

}

else if (second == '*')

{

fputc(first, pfWrite);

fputc('/', pfWrite);

state = C_STATE;//在无状态下遇到/*要将/*变成//写进去,并进入c状态

}

else

{

fputc(first, pfWrite);

fputc(second, pfWrite);//如果遇到其他字符,直接写进去,状态不改变。

}

break;

case EOF:

state = END_STATE;//如果遇到EOF,进入结束状态

break;

case '"':

fputc(first, pfWrite);

state = STR_STATE;//如果遇到",进入字符串状态

break;

default:

fputc(first, pfWrite);//其他情况的字符,直接写进去就行

break;

}

}

void Do_STR_STATE(FILE *pfRead,FILE *pfWrite)

{

int first = 0;

first = fgetc(pfRead);

switch (first)

{

case '"':

fputc(first, pfWrite);

state = NUL_STATE;//在字符串状态如果遇到后引号,将后引号写入,并进入无状态

break;

default:

fputc(first, pfWrite);//其他情况的字符,直接写进去就行

break;

}

}

void Do_C_STATE(FILE *pfRead, FILE *pfWrite)

{

int first = 0;

int second = 0;

int third = 0;

first = fgetc(pfRead);

switch (first)

{

case '*':

second = fgetc(pfRead);

if (second == '/') // 遇到*/ 说明c的注释结束,切换到无状态

{

state = NUL_STATE;

third = fgetc(pfRead);

if (third != '\n')

{

fputc('\n', pfWrite); //如果/后边的字符不是回车,需要写进去回车,然后再把独到的字符放回

ungetc(third, pfRead);

}

else

{

ungetc(third, pfRead);//如果是回车,把回车放回

}

}

else

{

fputc(first, pfWrite);

//如果遇到*,但是后边不是/,把*放进去,*后边的字符放回,比如,/***/,进入c状态以后,

//遇到*,后边的字符也是*,如果把两个*都写进去,后边就只剩下/,就不能找到c状态结束的标志,

//所以,需要把第二个字符原样写回

/*fputc(second, pfWrite);*/

ungetc(second,pfRead); //放回

}

break;

case '\n':

fputc(first, pfWrite);//如果需要回车,吧回车写入,在写入//,状态不变。

fputc('/', pfWrite);

fputc('/', pfWrite);

break;

default:

fputc(first, pfWrite);

break;

}

}

void Do_CPP_STATE(FILE *pfRead, FILE *pfWrite)

{

int first = 0;

int second = 0;

first = fgetc(pfRead);

switch (first)

{

case '\n':

fputc(first,pfWrite);//cpp状态,如果遇到回车,cpp状态结束,进入无状态

state = NUL_STATE;

break;

default:

if (first == EOF)

{

state = END_STATE;

}

else

{

fputc(first, pfWrite);

}

break;

}

}

加入代码之后,竟然发现好丑~~~希望理解。

代码的测试用例:

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

下边我来谈一下关于写代码时的一些失误:

1.写代码之前,没有将思路整理好,导致出错了也不知道从哪开始调试,排查。

2.对有限状态转移的不理解:比如c状态下没有遇到*/,遇到了其他一般字符,仍然需要

停留在c状态;还有,状态被改变之后,不用人为地调用commentconvert函数,因为进

入当前状态是从commentconvert函数进入的,所以结束当前状态后也会回到commentconvert函数,while循环帮我们实现了。也是因为多余。。

3.state是一个全局变量,软件工程课学到,尽量不要使用全局变量,是因为它不安全,

想改就能改,根据他的这个特性,我们可以做到状态转换。但是,定义全局变量,你也

不要得寸进尺----将全局变量定义在头文件中,这样全局变量在每个文件中都可以被使

用,被改变,而我们只要在我们当前的文件中使用。如果一个工程不是一个人完成,那

么其他人的不留意也会改变它,所以,这样就不好了。(反正意思就是这个了)

4.打开文件就关闭文件,如果读取打开失败,关闭文件再报告错误;如果程序顺利执行

之后,也要关闭文件,粗心的我并没有关闭,以下这两句代码:

fclose(pfRead);

fclose(pfWrite);

应该添加在测试文件的

commentconvert函数调用之后。

这是我在写这个小项目过程中遇到的问题,希望读者会注意~~当然,还有谁会像我这么

笨,犯这样的错误~~

0818b9ca8b590ca3270a3433284dd417.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值