C语言注释与C++注释的相互转换
做此項目的經(jīng)歷主要的收獲是熟悉了狀態(tài)機這一方法的使用,還有就是對每實現(xiàn)一個功能就盡量封裝一個函數(shù)這一概念把握的更為精到。
狀態(tài)機:關(guān)于狀態(tài)機的一個極度確切的描述是它是一個有向圖形,由一組節(jié)點和一組相應的轉(zhuǎn)移函數(shù)組成。狀態(tài)機通過響應一系列事件而“運行”。每個事件都在屬于“當前” 節(jié)點的轉(zhuǎn)移函數(shù)的控制范圍內(nèi),其中函數(shù)的范圍是節(jié)點的一個子集。函數(shù)返回“下一個”(也許是同一個)節(jié)點。這些節(jié)點中至少有一個必須是終態(tài)。當?shù)竭_終態(tài), 狀態(tài)機停止。(百度摘抄)
首先說明:
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 //狀態(tài)機 {NULL_STATE, //無狀態(tài),即不做任何處理C_STATE, //C注釋狀態(tài)CPP_STATE, //CPP注釋狀態(tài)STRING_STATE, //字符串狀態(tài) END_STATE //結(jié)束狀態(tài) }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);#endif2、實現(xiàn)聲明的.c文件
#include "CommentConvert.h"Con_state state = NULL_STATE; //聲明一個全局的狀態(tài)機變量void menu() {printf("*******************************************\n");printf(" 注釋轉(zhuǎn)換 \n");printf(" 請選擇程序要實現(xiàn)的功能 \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) //遇到不同的情況,進入不同的狀態(tài){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語言注釋已經(jīng)結(jié)束了,后面的數(shù)據(jù)//不再是注釋的一部分,而此時本行數(shù)據(jù)已經(jīng)被“//”修飾為注釋內(nèi)容,要是不換行,“*/”//后面的數(shù)據(jù)也會被當做是注釋的一部分,即使“*/”后面仍為注釋,那么也最好輸出回車,//因為這是兩塊相互獨立的注釋,不換行,就會被認為是一條注釋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語言注釋的結(jié)束標志,所以需要回退一個字符,判斷此時連續(xù)讀取的兩個字符會不會是*/}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) //遇到不同的狀態(tài),進入不同的函數(shù){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("請輸入轉(zhuǎn)換文件的路徑及文件名:");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("轉(zhuǎn)換成功!\n");printf("請選擇是否繼續(xù)轉(zhuǎn)換其他文件,輸入:y -->>繼續(xù)轉(zhuǎn)換,輸入:n結(jié)束轉(zhuǎn)換\n");printf("請輸入>");fflush(stdin); //因為scanf()函數(shù)是以回車結(jié)束的,而回車不會被統(tǒng)計到上一次的輸入而被讀入,//而是殘留在緩沖區(qū),所以此處直接用scanf()函數(shù)讀取一個字符的話,讀到的就是'\n',//因此這里要用fflush()清空緩沖區(qū)scanf("%c", &select);if (select == 'y'){system("cls");}else{input = 0;}break;case 2:printf("請輸入轉(zhuǎn)換文件的路徑及文件名:");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("轉(zhuǎn)換成功!\n");printf("請選擇是否繼續(xù)轉(zhuǎn)換其他文件,輸入:y -->>繼續(xù)轉(zhuǎn)換,輸入:n結(jié)束轉(zhuǎ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、用于測試函數(shù)功能的測試文件
int main() {CommentConvert();system("pause");return 0; }程序?qū)崿F(xiàn)的靠幾個主要的函數(shù),每個函數(shù)的作用幾乎都能見名知其義(雖然名字起的很丑很丑很丑),程序邏輯只要從測試函數(shù)一點一點開始看起,都能看懂
接下來給出結(jié)果:
以上就是程序運行及得到的結(jié)果(圖片有些模糊),在此只做了C語言注釋到CPP注釋的轉(zhuǎn)換,CPP注釋到C語言注釋的轉(zhuǎn)換與之相似
總結(jié)
以上是生活随笔為你收集整理的C语言注释与C++注释的相互转换的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不同类型的变量与零值比较的方法
- 下一篇: 初识C++之虚函数