C程序注释移除异常:单行注释仅删除一个'/'的修复求助
我来帮你解决单行注释残留/的问题!咱们先拆解代码里的几个关键问题,再给出修复后的完整代码。
问题根源分析
- 局部变量屏蔽全局变量:你的
single_comment函数里重新声明了char c,d;,这会把全局的c和d给覆盖掉。函数里读取的字符根本不会更新全局变量,所以处理完单行注释后,全局的d还是之前的/,后续代码就会错误地把这个残留的/输出出去。 check_comment逻辑漏洞:在else分支里,不管当前字符是什么,你都同时输出c和d,这不仅会导致字符重复输出,而且处理完单行注释后,没有跳过这个错误的输出逻辑。- 多行注释处理逻辑错误:
incomment里的循环条件while(c == '*' || c == '/')完全不对,它没法正确识别多行注释的结束标记*/,很可能提前退出或者漏掉部分注释。 - 全局变量初始化缺失:全局的
d没有初始值,容易引发未知的奇怪行为。
针对性解决方案
针对这些问题,我们一步步调整代码:
- 删掉
single_comment里的局部变量,直接用全局变量来跟踪字符状态; - 重构
check_comment的输出逻辑,只在确定不是注释的情况下输出字符,避免重复或错误输出; - 修复
incomment的循环,正确识别*/来结束多行注释; - 增加参数检查和更严谨的错误处理,避免资源泄漏。
修复后的完整代码
/*Program to remove all the comments from a c program */ #include<stdio.h> #include<stdlib.h> void check_comment(); void incomment(); void single_comment(); char c; // 只保留全局的当前字符变量,简化状态管理 FILE *fp, *fp1; int main(int argc, char** argv) { // 先检查命令行参数是否正确 if (argc != 3) { printf("Usage: %s <input-file> <output-file>\n", argv[0]); exit(EXIT_FAILURE); } // 输入文件只读打开 fp = fopen(argv[1], "r"); if (fp == NULL) { perror("Error opening input file"); exit(EXIT_FAILURE); } // 输出文件写打开 fp1 = fopen(argv[2], "w"); if (fp1 == NULL) { perror("Error opening output file"); fclose(fp); // 打开失败时记得关闭已打开的输入文件 exit(EXIT_FAILURE); } // 逐字符处理输入文件 while ((c = fgetc(fp)) != EOF) { check_comment(); } // 关闭文件资源 fclose(fp); fclose(fp1); return 0; } void check_comment() { if (c == '/') { char next_char = fgetc(fp); // 临时读取下一个字符,不覆盖全局c if (next_char == '*') { // 进入多行注释处理 incomment(); } else if (next_char == '/') { // 进入单行注释处理 single_comment(); } else { // 不是注释,输出当前字符,把读取的下一个字符放回输入流 fputc(c, fp1); if (next_char != EOF) { ungetc(next_char, fp); } } } else { // 正常字符直接输出 fputc(c, fp1); } } /* 处理多行注释:直到找到 */ 结束标记 */ void incomment() { char prev_char = '*'; // 初始为*,因为已经读取了 /* while ((c = fgetc(fp)) != EOF) { if (prev_char == '*' && c == '/') { break; // 找到注释结束符,退出循环 } prev_char = c; } } /* 处理单行注释:跳过直到换行,保留换行符 */ void single_comment() { while ((c = fgetc(fp)) != EOF) { if (c == '\n') { // 保留换行符,保证输出代码格式正确 fputc(c, fp1); break; // 回到主循环处理下一行 } // 跳过单行注释中的所有字符 } }
关键修改说明
- 简化全局变量:只保留全局的
c来跟踪当前读取的字符,减少全局变量带来的状态混乱; - 修复单行注释:移除
single_comment里的局部变量,直接使用全局c,并且保留换行符(让输出的代码格式更自然); - 正确处理多行注释:用
prev_char记录前一个字符,准确识别*/结束标记,确保完整移除多行注释; - 严谨的错误处理:增加命令行参数检查,打开文件失败时关闭已打开的资源,避免内存泄漏;
- 避免重复输出:使用
ungetc把误读的非注释字符放回输入流,保证后续字符处理的连贯性。
这样修改后,单行注释会被完整移除,不会残留/,多行注释也能正确处理,输出的代码格式也和原文件保持一致。
内容的提问来源于stack exchange,提问作者Santosh
相关产品推荐
相关产品推荐

