如何在C++括号匹配功能中正确处理单引号内的转义序列
C++括号匹配检查代码问题排查及修复
已确认的错误点
- 块注释关闭逻辑错误:原代码中结束块注释的操作为
note2 == false,属于相等判断而非赋值,导致块注释一旦开启就无法关闭,后续所有字符都会被判定为处于注释中。 - 数组越界风险:所有访问
ch[i+1]的位置都未判断i是否小于字符串长度减1,当遍历到字符串最后一个字符时,i+1会超出合法索引范围,触发未定义行为。 - 转义逻辑不合理:当前代码无论是否处于引号范围内,只要遇到
\就跳过下一个字符,实际上只有单引号、双引号内部的转义序列才需要跳过,非引号范围内的\无转义含义不需要特殊处理。 - 注释符号匹配后未跳过后续字符:匹配到
//或者/*之后,没有跳过第二个符号,下一轮循环会重复处理第二个/或者*,可能引发逻辑错误。 - 行号计数逻辑错误:仅遇到换行时才对
nline加1,会导致第一行的错误行号显示为0;匹配到多余右括号时强制对nline加1,会输出错误的行号。 - 多余右括号返回值错误:匹配到多余右括号时返回
!check.empty(),此时check为空,会错误返回false,与函数返回值逻辑不符。
修复后代码
#include <iostream> #include <stack> #include <string> bool checkMatching(std::string ch) { std::stack<char> check; int nline = 1; // 初始行号为1,符合常规计数习惯 int ncount = 0; bool quot = false; // 单引号标记 bool Bigquot = false; // 双引号标记 bool note1 = false; // 单行注释标记 bool note2 = false; // 块注释标记 for (int i = 0; i < ch.length(); i++) { // 仅引号内部处理转义序列 if ((quot || Bigquot) && ch[i] == '\\') { if (i + 1 < ch.length()) { // 防止越界 i++; } continue; } // 单行注释处理 if (!note1 && !note2 && i + 1 < ch.length() && ch[i] == '/' && ch[i + 1] == '/') { note1 = true; i++; // 跳过第二个/ continue; } else if (ch[i] == '\n') { note1 = false; nline++; continue; } // 块注释处理 if (!note1 && !note2 && i + 1 < ch.length() && ch[i] == '/' && ch[i + 1] == '*') { note2 = true; i++; // 跳过* continue; } else if (note2 && i + 1 < ch.length() && ch[i] == '*' && ch[i + 1] == '/') { note2 = false; i++; // 跳过/ continue; } // 处于注释状态直接跳过后续判断 if (note1 || note2) { continue; } // 单引号处理 if (ch[i] == '\'' && !quot && !Bigquot) { quot = true; } else if (ch[i] == '\'' && quot) { quot = false; ncount++; } // 双引号处理 if (ch[i] == '"' && !Bigquot && !quot) { Bigquot = true; } else if (ch[i] == '"' && Bigquot) { Bigquot = false; } // 处于引号状态跳过括号判断 if (quot || Bigquot) { continue; } // 左括号入栈 if (ch[i] == '(' || ch[i] == '{' || ch[i] == '[') { check.push(ch[i]); } // 右括号匹配 if (ch[i] == ')' || ch[i] == '}' || ch[i] == ']') { if (check.empty()) { std::cout << "Error," << " Line_count : " << nline << "," << " quotes_count : " << ncount << std::endl; return false; } char prev = check.top(); check.pop(); if (!((prev == '(' && ch[i] == ')') || (prev == '{' && ch[i] == '}') || (prev == '[' && ch[i] == ']'))) { std::cout << "Error," << " Line_count : " << nline << "," << " quotes_count : " << ncount << std::endl; return false; } } } // 最终状态判断:括号匹配、无未闭合引号、无未闭合块注释才返回正常 if (check.empty() && !quot && !Bigquot && !note2) { std::cout << "OK," << " Line_count : " << nline << "," << " quotes_count : " << ncount << std::endl; return true; } else { std::cout << "Error," << " Line_count : " << nline << "," << " quotes_count : " << ncount << std::endl; return false; } }
内容的提问来源于stack exchange,提问作者cgi
相关产品推荐
相关产品推荐

