做此项目的经历主要的收获是熟悉了状态机这一方法的使用,还有就是对每实现一个功能就尽量封装一个函数这一概念把握的更为精到。

状态机:关于状态机的一个极度确切的描述是它是一个有向图形,由一组节点和一组相应的转移函数组成。状态机通过响应一系列事件而“运行”。每个事件都在属于“当前” 节点的转移函数的控制范围内,其中函数的范围是节点的一个子集。函数返回“下一个”(也许是同一个)节点。这些节点中至少有一个必须是终态。当到达终态, 状态机停止。(百度摘抄)

首先说明:
C语言注释是以斜杠星开始到第一次遇到星斜杠为止的一个字符串
CPP注释是以双斜杠开始,直到遇到回车为止的一个字符串

1、放声明的头文件

#ifndef __COMMENTCONVERT_HEADFILE__     //预编译指令
#define __COMMENTCONVERT_HEADFILE__#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#define MAX_NUMBER_OF_CHAR 50typedef enum Convert_state    //状态机
{NULL_STATE,     //无状态,即不做任何处理C_STATE,        //C注释状态CPP_STATE,      //CPP注释状态STRING_STATE,   //字符串状态 END_STATE       //结束状态
}Con_state;//void CommentConvert();
//void C_Convert_To_CPP(FILE *fread, FILE* fwrite);
//void CPP_Convert_To_C(FILE *fread, FILE* fwrite);
//void Null_State_of_C_Con_CPP(FILE *fread, FILE* fwrite);
//void C_State_of_C_Con_CPP(FILE *fread, FILE* fwrite);
//void Cpp_State_of_C_Con_CPP(FILE *fread, FILE* fwrite);
//void Null_State_of_CPP_Con_C(FILE *fread, FILE* fwrite);
//void C_State_of_CPP_Con_C(FILE *fread, FILE* fwrite);
//void Cpp_State_of_CPP_Con_C(FILE *fread, FILE* fwrite);
//void String_Convert(FILE *fread, FILE* fwrite);#endif 

2、实现声明的.c文件

#include "CommentConvert.h"Con_state state = NULL_STATE;    //声明一个全局的状态机变量void menu()
{printf("*******************************************\n");printf("                   注释转换                \n");printf("            请选择程序要实现的功能         \n");printf("               [1] C----->>CPP             \n");printf("               [2] CPP----->>C             \n");printf("               [0]    EXIT                 \n");printf("*******************************************\n");printf("请选择>");
}void Null_State_of_C_Con_CPP(FILE *fread, FILE* fwrite)
{int ch = fgetc(fread);switch (ch)     //遇到不同的情况,进入不同的状态{int next_ch = 0;case '/':next_ch = fgetc(fread);if (next_ch == '*'){fputc(ch, fwrite);fputc('/', fwrite);state = C_STATE;}else if (ch == '/'){fputc(ch, fwrite);fputc(next_ch, fwrite);state = CPP_STATE;}else{fputc(ch, fwrite);fputc(next_ch, fwrite);}break;case '"':fputc(ch, fwrite);state = STRING_STATE;break;case EOF:fputc(ch, fwrite);state = END_STATE;break;default:fputc(ch, fwrite);break;}
}void C_State_of_C_Con_CPP(FILE *fread, FILE* fwrite)
{int ch = fgetc(fread);switch (ch){int next_ch = 0;case '*':next_ch = fgetc(fread);if (next_ch == '/'){char frith_ch = fgetc(fread);if (('\n' != frith_ch) && (EOF != frith_ch)){fputc('\n', fwrite);  //输出回车是因为要是在C语言注释里遇到“*/”,说明C语言注释已经结束了,后面的数据//不再是注释的一部分,而此时本行数据已经被“//”修饰为注释内容,要是不换行,“*/”//后面的数据也会被当做是注释的一部分,即使“*/”后面仍为注释,那么也最好输出回车,//因为这是两块相互独立的注释,不换行,就会被认为是一条注释fseek(fread, -1, SEEK_CUR);}else{fputc(frith_ch, fwrite);}state = NULL_STATE;}else if (next_ch == '*'){fputc(ch, fwrite);fseek(fread, -1, SEEK_CUR);//在此需要回退一个自己的指针,是因为碰到**之后可能接下来的字符时是/,那么会和它的上一个字符*组成一个*/,成为C语言注释的结束标志,所以需要回退一个字符,判断此时连续读取的两个字符会不会是*/}else{fputc(ch, fwrite);fputc(next_ch, fwrite);}break;case EOF:fputc(ch, fwrite);state = END_STATE;break;case '\n':fputc(ch, fwrite);fputc('/', fwrite);fputc('/', fwrite);break;default:fputc(ch, fwrite);break;}
}void Cpp_State_of_C_Con_CPP(FILE *fread, FILE* fwrite)
{int ch = fgetc(fread);switch (ch){case '\n':fputc(ch, fwrite);state = NULL_STATE;break;case EOF:fputc(ch, fwrite);state = END_STATE;break;default:fputc(ch, fwrite);break;}
}void Null_State_of_CPP_Con_C(FILE *fread, FILE* fwrite)
{int ch = fgetc(fread);switch (ch){int next_ch = 0;case '/':next_ch = fgetc(fread);if (next_ch == '*'){fputc(ch, fwrite);fputc(next_ch, fwrite);state = C_STATE;}else if (ch == '/'){fputc(ch, fwrite);fputc('*', fwrite);state = CPP_STATE;}else{fputc(ch, fwrite);fputc(next_ch, fwrite);}break;case '"':fputc(ch, fwrite);state = STRING_STATE;break;case EOF:fputc(ch, fwrite);state = END_STATE;break;default:fputc(ch, fwrite);break;}
}void C_State_of_CPP_Con_C(FILE *fread, FILE* fwrite)
{int ch = fgetc(fread);switch (ch){int next_ch = 0;case '*':next_ch = fgetc(fread);if (next_ch == '/'){fputc(ch, fwrite);fputc(next_ch, fwrite);state = NULL_STATE;}else if (next_ch == '*'){fputc(ch, fwrite);fseek(fread, -1, SEEK_CUR);}else{fputc(ch, fwrite);fputc(next_ch, fwrite);}break;case EOF:fputc(ch, fwrite);state = END_STATE;break;default:fputc(ch, fwrite);break;}
}void Cpp_State_of_CPP_Con_C(FILE *fread, FILE* fwrite)
{int ch = fgetc(fread);switch (ch){case '\n':fputc('*', fwrite);fputc('/', fwrite);fputc(ch, fwrite);state = NULL_STATE;break;case EOF:fputc(ch, fwrite);state = END_STATE;break;default:fputc(ch, fwrite);break;}
}void String_Convert(FILE *fread, FILE* fwrite)
{int ch = fgetc(fread);switch (ch){case '"':fputc(ch, fwrite);state = NULL_STATE;break;case EOF:fputc(ch, fwrite);state = END_STATE;break;default:fputc(ch, fwrite);break;}
}void C_Convert_To_CPP(FILE *fread, FILE* fwrite)
{while (state != END_STATE){switch (state)      //遇到不同的状态,进入不同的函数{case NULL_STATE:Null_State_of_C_Con_CPP(fread, fwrite);break;case C_STATE:C_State_of_C_Con_CPP(fread, fwrite);break;case CPP_STATE:Cpp_State_of_C_Con_CPP(fread, fwrite);break;case STRING_STATE:String_Convert(fread, fwrite);}}fclose(fread);fclose(fwrite);
}void CPP_Convert_To_C(FILE *fread, FILE* fwrite)
{while (state != END_STATE){switch (state){case NULL_STATE:Null_State_of_CPP_Con_C(fread, fwrite);break;case C_STATE:C_State_of_CPP_Con_C(fread, fwrite);break;case CPP_STATE:Cpp_State_of_CPP_Con_C(fread, fwrite);break;case STRING_STATE:String_Convert(fread, fwrite);}}fclose(fread);fclose(fwrite);
}void CommentConvert()
{int input = 1;char select = 'y';char input_file[MAX_NUMBER_OF_CHAR] = { 0 };char output_file[MAX_NUMBER_OF_CHAR] = { 0 };FILE *fread = NULL;FILE *fwrite = NULL;while (input){menu();scanf("%d", &input);switch (input){case 1:printf("请输入转换文件的路径及文件名:");scanf("%s", input_file);fread = fopen(input_file, "r");if (NULL == fread){perror("open file for read");exit("EXIT_FAILURE");}printf("请输入输出文件的路径及文件名:");scanf("%s", output_file);fwrite = fopen(output_file, "w");if (NULL == fwrite){fclose(fread);perror("open file for write");exit("EXIT_FAILURE");}C_Convert_To_CPP(fread, fwrite);printf("转换成功!\n");printf("请选择是否继续转换其他文件,输入:y -->>继续转换,输入:n结束转换\n");printf("请输入>");fflush(stdin);         //因为scanf()函数是以回车结束的,而回车不会被统计到上一次的输入而被读入,//而是残留在缓冲区,所以此处直接用scanf()函数读取一个字符的话,读到的就是'\n',//因此这里要用fflush()清空缓冲区scanf("%c", &select);if (select == 'y'){system("cls");}else{input = 0;}break;case 2:printf("请输入转换文件的路径及文件名:");scanf("%s", input_file);fread = fopen(input_file, "r");if (NULL == fread){perror("open file for read");exit("EXIT_FAILURE");}printf("请输入输出文件的路径及文件名:");scanf("%s", output_file);fwrite = fopen(output_file, "w");if (NULL == fwrite){fclose(fread);perror("open file for write");exit("EXIT_FAILURE");}CPP_Convert_To_C(fread, fwrite);printf("转换成功!\n");printf("请选择是否继续转换其他文件,输入:y -->>继续转换,输入:n结束转换\n");printf("请输入>");fflush(stdin);scanf("%c", &select);if (select == 'y'){system("cls");}else{input = 0;}break;break;case 0:exit(0);break;default:printf("输入有误,请重新输入!");system("cls");break;}}
}

3、用于测试函数功能的测试文件

int main()
{CommentConvert();system("pause");return 0;
}

程序实现的靠几个主要的函数,每个函数的作用几乎都能见名知其义(虽然名字起的很丑很丑很丑),程序逻辑只要从测试函数一点一点开始看起,都能看懂

接下来给出结果:

以上就是程序运行及得到的结果(图片有些模糊),在此只做了C语言注释到CPP注释的转换,CPP注释到C语言注释的转换与之相似

C语言注释与C++注释的相互转换相关推荐

  1. python语言中如何使用注释

    每一种计算机语言都有自己的注释方式,我们知道注释的作用是解释这些代码,方便程序员以后的检查和修改.而且注释的一部分在运行程序的过程中不起作用,也不会显示出来.下面我们将为大家介绍,在python语言中 ...

  2. 编写一个程序,实现将c语言源程序中的注释全部删除

    <程序设计基础-c语言>杨莉 刘鸿翔 ISBN-978-7-03-032903-5 p257 习题8 6.编写一个程序,实现将c语言源程序中的注释全部删除 #include<stdl ...

  3. C语言编程规范--------2 注释

    2.1 注释的原则 注释的目的是解释代码的目的.功能和采用的方法,提供代码以外的信息,帮助读者理解代码,防止没必要的重复注释信息. 示例:如下注释意义不大. /* if receive_flag is ...

  4. 线性分组码c语言实验报告,C语言线性分组码(附注释).doc

    C语言线性分组码(附注释).doc 下载提示(请认真阅读)1.请仔细阅读文档,确保文档完整性,对于不预览.不比对内容而直接下载带来的问题本站不予受理. 2.下载的文档,不会出现我们的网址水印. 3.该 ...

  5. c语言注释符号 井号,读c语言深度剖析 -- 符号 注释符号

    标准C语言的基本符号 ,逗号  >右尖括号  . 圆点 !感叹号   :分号   | 竖线   :冒号  /斜杠   ?问号  \反斜杠 '单引号  ~波折号  "双引号  #井号   ...

  6. C语言基础1:初识C语言(转义、注释;数组、操作符、反码、补码、static、define、指针、结构体常变量;局部变量;作用域、生命周期)

    文章目录 C语言基础1:初识C语言 1.C语言简介 1.1什么是C语言 1.2C语言的发展 2.第一个C语言程序 2.1创建项目 2.2添加源文件 2.3写代码 3.数据类型 4.变量.常量 4.1定 ...

  7. c语言注释两种,C语言有几种注释方式

    C语言有两种注释方式,一种是以/*开始,以*/结束的块注释:另一种是以//开始,以换行符结束的单行注释.具体使用方法如:[const double pi = 3.1415926536; // pi是- ...

  8. 利用有穷自动机去除C语言代码行注释(//)以及块注释(/* */)

    一. 程序设计题目与说明 利用有穷自动机去除C语言代码行注释(//)以及块注释(/* */) 该有穷自动机的状态转换图如下: 二. 核心代码(或全部代码) #include<stdio.h> ...

  9. c语言入门篇:注释定界符详解

    c语言的注释定界符是什么 1.最早期的C语言注释是:/**/ 2.后来又增加的行注释:// 其中/**/是多行注释,//是单行注释. 需要注意的是:C语言的注释并不是可以出现在C语言代码的任何地方. ...

最新文章

  1. The application could not be verified
  2. ML之LiRLassoR:利用boston房价数据集(PCA处理)采用线性回归和Lasso套索回归算法实现房价预测模型评估
  3. 【django】视图和URL
  4. 虚拟化宿主服务器网络设置,kvm虚拟化安装配置手册
  5. kotlin学习笔记——操作符
  6. Shell程序设计 | 基本语法 :变量、I/O、算术运算、条件判断、流程控制、函数
  7. Python小白的数学建模课-04.整数规划
  8. Java小 orm_这么优雅的Java ORM没见过吧!
  9. 康众平板探测器_2020-2025年数字化X线探测器行业市场深度调研及投资前景预测分析报告 数字化设备成为市场主流...
  10. CF1033A. King Escape的题解
  11. Android AndroidNSSP的简单说明
  12. 大数据项目流程(必须会)
  13. 干货分享:【IT-PMP学堂】PMP 文档与配置管理
  14. uniapp iOS打包
  15. DNK开发—Eclipse环境变量配置
  16. 【导数术】4.三次函数
  17. 实对称矩阵的一些性质(不包含证明)
  18. 【百练】护林员盖房子
  19. java计算机毕业设计网络招聘系统源码+系统+数据库+lw文档+mybatis+运行部署
  20. 2021-02-05仅供自己参考:多态使用

热门文章

  1. 第九弹 - 脚本模式与参数视图
  2. 阿里CTO张建锋:明年双11将大规模应用含光AI芯片
  3. 如何优化大规模推荐?下一代算法技术JTM来了
  4. 阿里CTO:阿里所有技术和产品输出都将必须通过阿里云进行
  5. 搞不定这三大难题,根本学不会Python,别不信!
  6. 扎根中国20年,F5“代码到用户”线上峰会盛大启幕
  7. 避免大规模故障的微服务架构设计之道
  8. 升级鸿蒙系统有没有翻车,被寄予厚望的华为鸿蒙系统,这次要翻车?原来并不是我们想的那样...
  9. php使用七牛直播,七牛上传文件,PHP版本
  10. php网站加广告位,HotNews Pro主题文章内容上面添加广告位