C语言 注释转换 迈不过友情╰ 2022-06-10 20:59 175阅读 0赞 在编写代码中,经常会注释掉某段代码,C语言一般有两种方式:一种是/\*xxxxxx\*/,另一种是://xxxxx.第一种注释方式不能嵌套使用,在/与\*的匹配上可能会造成理解错误,第二种注释可以注释掉一行,两种风格各有优缺点,今天讲一下怎样将第一种风格转换成第二种风格。 虽然转换本身不难,但要考虑到匹配时会出现多种情况,在这里,我们用到了状态机编程的思想。 定义四种状态:NUL\_STATE(无状态),C\_STATE(C状态),CPP\_STATE(C++状态),END\_STATE(结束状态);四种状态转化如下图所示: ![SouthEast][] 在input.c文件里输入需要转换的代码: // 1.一般情况 int i = 0; /* int j = 0; */ // 2.换行问题 /* int k = 0; */int m = 0; /* int tmp = 0; */ int n = 0; // 3.匹配问题 /*int k = 0;/*hehehe*/ // 4.多行注释问题 /* int i=0; int j = 0; int k = 0; */int m = 0; // 5.连续注释问题 /*abc*//*def*/ // 6.连续的**/问题 /****/ // 7.C++注释问题 // /*abcdef*/ 转换后的结果在output文件中 CommentConvert.h #ifndef __COMMEENT_CONVERT_H__ #define __COMMEENT_CONVERT_H__ #include <stdio.h> #include <stdlib.h> enum STATE { NUL_STATE, C_STATE, CPP_STATE, END_STATE }; void DoNulState(FILE* pfIn, FILE* pfOut, enum STATE* state); void DoCState(FILE* pfIn, FILE* pfOut, enum STATE* state); void DoCppState(FILE* pfIn, FILE* pfOut, enum STATE* state); #endif//__COMMEENT_CONVERT_H__ CommentConvert.c #define _CRT_SECURE_NO_WARNINGS #include "CommentConvert.h" void DoNulState(FILE* pfIn, FILE* pfOut, enum STATE* s) { int first = fgetc(pfIn); switch (first) { case '/': { int second = fgetc(pfIn); switch (second) { case '/': *s = CPP_STATE;//遇到//转换至C++状态 fputc(first, pfOut); fputc(second, pfOut); break; case '*'://将/*转换成//,转换至C状态 *s = C_STATE; fputc('/', pfOut); fputc('/', pfOut); break; default: fputc(second, pfOut); } } break; case EOF: *s = END_STATE;//文件结束,转换至结束状态 break; default: fputc(first, pfOut); break; } } void DoCState(FILE* pfIn, FILE* pfOut, enum STATE* s) { int first = fgetc(pfIn); switch (first) { case '*': { int second = fgetc(pfIn); switch (second) { case '/'://遇到*/转换至无状态,将*/去除或换行 { *s = NUL_STATE; int third = fgetc(pfIn); if (third != '\n') { fputc('\n', pfOut); ungetc(third, pfIn); } else { fputc(third, pfOut); } } break; case '*': fputc(first, pfOut); ungetc(second, pfIn); break; default: fputc(first, pfOut); fputc(second, pfOut); break; } } break; case '\n'://多行注释的处理 fputc(first, pfOut); fputc('/', pfOut); fputc('/', pfOut); break; case EOF://文件结束,转换至无状态 *s = END_STATE; break; default: fputc(first, pfOut); break; } } void DoCppState(FILE* pfIn, FILE* pfOut, enum STATE* s) { int first = fgetc(pfIn); switch (first) { case '\n': *s = NUL_STATE;//C++状态注释一行结束,转换至无状态 fputc(first, pfOut); break; case EOF: *s = END_STATE; break; default: fputc(first, pfOut); break; } } test.c #define _CRT_SECURE_NO_WARNINGS #include "CommentConvert.h" void CommentConvert(FILE* pfIn, FILE* pfOut) { enum STATE state = NUL_STATE; while (state != END_STATE) { switch (state) { case NUL_STATE: DoNulState(pfIn, pfOut, &state); break; case C_STATE: DoCState(pfIn, pfOut, &state); break; case CPP_STATE: DoCppState(pfIn, pfOut, &state); break; } } } void test() { FILE* pfIn = 0; FILE* pfOut = 0; pfIn = fopen("input.c", "r"); if (pfIn == NULL) { perror("open for read"); exit(EXIT_FAILURE); } pfOut = fopen("output.c", "w"); if (pfOut == NULL) { perror("open for write"); fclose(pfIn); exit(EXIT_FAILURE); } CommentConvert(pfIn, pfOut); fclose(pfIn); fclose(pfOut); } int main() { test(); return 0; } 运行结果如下图: ![SouthEast 1][] [SouthEast]: /images/20220611/6e7cd00bc09443f58ecbe31ca17cf825.png [SouthEast 1]: /images/20220611/445050af4e3046458f38b03e3b29c987.png
还没有评论,来说两句吧...