每个程序员的代码注释风格不同,为统一代码注释风格,有时需要将c++注释转化为c语言注释或者反之,人工修改速度太慢,且容易出错,要是有一个专门负责注释代码转化的程序,必定事半功倍!!
题目要求:
注释转化要求如下:
注释的嵌套情形很多,这里只是举例,你需要遵照C/C++语言的注释规则来编写代码,我不会仅测试这里的例子。
1、单行注释或没有嵌套,注释行直接转换,如:
①//123 /* 123 */
②/* 123 */ /* 123 */ 不变
③/*123
*/ 保持原样
2、有嵌套的注释(一个注释中还有嵌套其他注释符号//,/* */)嵌套中多余的每个注释符号用两个空格代替。
如单行:
① //123 /*456 */ /*123 456*/
②//123//456 /*123 456*/
③//123*//*456 /*123 456*/
如跨行
/*…….. /*……..
//……… ……….
// …….. ……….
*/ */
注意事项:
1、除以下两种情况的修改,源文件转换后不能有任何其它的修改:
①多余的注释符用空格代替
②//在注释开始替换为/* ,行尾增加*/
2、下面的3种情形无需转换
① /* 123 */ /* 456 */
②/* 123 */ /* 456
*/
③/* 123
*/ /* 456
*/
3、不需要考虑输入文件中不符合语法规则的注释
代码如下:
CommentConvert.cpp
#include<iostream> using namespace std; #define UL unsigned long extern int CommentConvert(FILE *inputfile, FILE *outputfile);//引入外部函数 /*枚举:各种状态*/ typedef enum { NO_COMMENT_STATE, //无注释状态 C_COMMENT_STATE, //c语言注释状态 CPP_COMMENT_STATE,//c++注释状态 STR_STATE, //字符串状态 END_STATE //结束状态,终态--状态机停止 }STATE_ENUM; /*结构体:状态机*/ typedef struct { FILE *inputfile; FILE *outputfile; STATE_ENUM ulstate; }STATE_MACHINE; // STATE_MACHINE g_state = {0}; /////////////////////////////////////////////////// /*各类事件*/ void EventPro(char ch); void EventProAtNo(char ch); void EventProAtC(char ch); void EventProAtCpp(char ch); void EventProAtStr(char ch); //////////////////////////////////////////////////// int CommentConvert(FILE *inputfile, FILE *outputfile) { if(inputfile==NULL || outputfile==NULL) { cout<<"input argument Invalid!"<<endl; return -1; } g_state.inputfile = inputfile; g_state.outputfile = outputfile; g_state.ulstate = NO_COMMENT_STATE; char ch; while(g_state.ulstate != END_STATE) { ch = fgetc(g_state.inputfile); // EventPro(ch); } return 0; } void EventPro(char ch)//驱动模型:由某一状态触发某一事件 { switch(g_state.ulstate) { case NO_COMMENT_STATE: EventProAtNo(ch); break; case C_COMMENT_STATE: EventProAtC(ch); break; case CPP_COMMENT_STATE: EventProAtCpp(ch); break; case STR_STATE: EventProAtStr(ch); break; case END_STATE: break; } } /*初始状态开始:可能转化:c注释,c++注释,终态,字符串状态*/ void EventProAtNo(char ch) { char nextch; switch(ch) { case '/': // // /* nextch = fgetc(g_state.inputfile); if(nextch == '/') // C++注释开始,按c注释打印 { fputc('/',g_state.outputfile); fputc('*',g_state.outputfile); g_state.ulstate = CPP_COMMENT_STATE; } else if(nextch == '*') //C注释开始,原样打印 { fputc(ch,g_state.outputfile); fputc(nextch,g_state.outputfile); g_state.ulstate = C_COMMENT_STATE; } else {} break; case '"'://字符串状态 fputc(ch,g_state.outputfile); g_state.ulstate = STR_STATE; break; case EOF://终态 g_state.ulstate = END_STATE; break; default: fputc(ch,g_state.outputfile); break; } } /*c注释状态:可能遇到:c注释结束-->终态 c注释(空格代替),c++注释(空格代替),字符串状态(中的注释不改变)*/ void EventProAtC(char ch) { char nextch; switch(ch) { case '*': nextch = fgetc(g_state.inputfile); if(nextch == '/')//c语言注释结束 { fputc(ch,g_state.outputfile); fputc(nextch,g_state.outputfile); g_state.ulstate = NO_COMMENT_STATE; } else { fputc(ch,g_state.outputfile); //只有一个*号,将其打印 fseek(g_state.inputfile,-1,1);//因为求nextch时调用fgetc,指针后移了一位,所以得将指针前移一位,否则会跳过一个字符 } break; case '/': nextch = fgetc(g_state.inputfile); if(nextch == '/' || nextch == '*')//掺杂c++或者c语言注释,用两个空格代替 { fputc(' ',g_state.outputfile); fputc(' ',g_state.outputfile); } else { fputc(ch,g_state.outputfile); //只有一个/号,将其直接打印 fseek(g_state.inputfile,-1,1);//因为求nextch时调用fgetc,指针后移了一位,所以得将指针前移一位,否则会跳过一个字符 } break; case '"'://字符串状态 fputc(ch,g_state.outputfile); g_state.ulstate = STR_STATE; break; default: fputc(ch,g_state.outputfile); break; } } //c++注释状态中可能包含:c注释(空格代替),c++注释(空格代替),字符串状态(中的注释不改变) void EventProAtCpp(char ch) { //123 /*123 char nextch; switch(ch) { case EOF: fputc('*',g_state.outputfile); fputc('/',g_state.outputfile); g_state.ulstate = END_STATE; break; case '*': nextch = fgetc(g_state.inputfile); if(nextch == '/')//掺杂其他注释,用两个空格代替 { fputc(' ',g_state.outputfile); fputc(' ',g_state.outputfile); } else { fputc(ch,g_state.outputfile); fseek(g_state.inputfile,-1,1); } break; case '/': nextch = fgetc(g_state.inputfile); if(nextch == '*')//掺杂c语言注释,用两个空格代替 { fputc(' ',g_state.outputfile); fputc(' ',g_state.outputfile); } else if(nextch == '/')//掺杂c++注释,用两个空格代替 { fputc(' ',g_state.outputfile); fputc(' ',g_state.outputfile); } else { fputc(ch,g_state.outputfile); fseek(g_state.inputfile,-1,1); } break; case '"'://字符串状态 fputc(ch,g_state.outputfile); g_state.ulstate = STR_STATE; break; default: fputc(ch,g_state.outputfile); break; } } /*字符串状态:c注释(原样输出)c++注释(原样输出),终态*/ void EventProAtStr(char ch) { char nextch; switch(ch) { case '\0': nextch = fgetc(g_state.inputfile); if(nextch == '"') { fputc(ch,g_state.outputfile); fputc(nextch,g_state.outputfile); g_state.ulstate = NO_COMMENT_STATE; } break; case EOF: g_state.ulstate = END_STATE; default: fputc(ch,g_state.outputfile); break; } }main.cpp
#include<iostream> using namespace std; extern int CommentConvert(FILE *inputfile, FILE *outputfile); int main() { FILE *fpIn = NULL; //inputfile FILE *fpOut = NULL; //outputfile fpIn = fopen("input.c","r"); if(NULL == fpIn) { cout<<"Open input file fail!"<<endl; return -1; } fpOut = fopen("output.c","w"); if(NULL == fpOut) { cout<<"Open output file fail!"<<endl; return -1; } CommentConvert(fpIn,fpOut); // fclose(fpIn); fclose(fpOut); return 0; }
测试用例如下
输入input.c:
//abc**def //每个区由若干个内存块组成 //每个区由若干个内存块组成,//每个块是4096个字节 //int i = 0;*/ //*//*int i = 0; // /**/int i = 0; /* int i = 0; *//* */ /* int i = 0; //*/int j = 0; /* //每个区由若干个内存块组成,每个块是4096个字节 //每个块的第0个整数指向下个区 //所以是单链表结构 //所以每个区只有4092个字节存放真正的数据 */ /* int i = 0;*//*int j = 0; */ /* *//* */int i =0; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 5 char *s = "abcdefghijklmn//~~/*~~*/!!!!!!!!";
/*abc**def*/ /*每个区由若干个内存块组成*/ /*每个区由若干个内存块组成*/ /*int i = 0; */ /* int i = 0;*/ /* int i = 0;*/ /* int i = 0; *//* */ /* int i = 0; */int j = 0; /* 每个区由若干个内存块组成,每个块是4096个字节 每个块的第0个整数指向下个区 所以是单链表结构 所以每个区只有4092个字节存放真正的数据 */ /* int i = 0;*//*int j = 0; */ /* *//* */int i =0; /* 5*/ char *s = "abcdefghijklmn//~~/*~~*/!!!!!!!!";
原文地址:http://blog.csdn.net/zongyinhu/article/details/46636327