编写一个算法,检测一个C++源程序文件中的括号是否配对,包括“()[]{}”这三类括号。需要注意的是,单个括号字符,字符串中的括号,注释中的括号均不列入检测范围。用C编写程序实现该算法。
时间: 2024-10-06 14:03:22 浏览: 136
为了编写这样一个算法,我们可以采用栈数据结构。当遇到左括号("("、 "[" 或 "{")时,我们将它压入栈中;当遇到右括号时,检查栈顶元素是否与其匹配,如果匹配则弹出栈顶元素,如果不匹配,则返回错误信息表示括号不配对。如果遍历完整个文件后栈为空,说明所有括号都已成功配对。
以下是C语言的一个简单实现:
```c
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
bool isPair(char ch, char last) {
// 根据括号类型判断是否匹配
switch (ch) {
case '(': return last == ')';
case '[': return last == ']';
case '{': return last == '}';
default: return false;
}
}
void checkBrackets(const char* filename) {
FILE *file = fopen(filename, "r");
if (!file) {
printf("Error opening file %s.\n", filename);
return;
}
int stack_size = 0;
stack_t brackets = { .size = 0, .items = NULL };
char prev_char = '\0';
while (true) {
int c = fgetc(file);
if (c == EOF) {
break;
} else if (c == '\n' || c == '\t' || c == ' ') { // 跳过空白字符
continue;
} else if (c == '/' && file[c + 1] == '/') { // 忽略单行注释
for (; file[fgetc(file)] != '\n';); // 遍历到换行符
continue;
} else if (c == '*' && file[c + 1] == '*') { // 忽略多行注释
bool in_comment = true;
for (; file[fgetc(file)] != '*' || file[fgetc(file) + 1] != '/';) {
if (in_comment) {
if (file[fgetc(file)] == EOF) {
printf("Unclosed comment in %s.\n", filename);
fclose(file);
return;
}
}
}
file[fgetc(file)]; // 消耗*/结束注释
continue;
} else if (c == '(' || c == '[' || c == '{') { // 压入栈
brackets.items = realloc(brackets.items, ++brackets.size * sizeof(brackets.items[0]));
brackets.items[brackets.size - 1] = c;
prev_char = c;
} else if (isPair(c, prev_char)) { // 匹配的话,弹出栈顶元素
stack_size--;
if (stack_size < 0) {
printf("Unmatched bracket in %s.\n", filename);
fclose(file);
return;
}
prev_char = brackets.items[brackets.size];
} else { // 不匹配,直接跳过
prev_char = c;
}
}
if (stack_size > 0) {
printf("Unmatched brackets at the end of %s.\n", filename);
} else {
printf("%s has balanced brackets.\n", filename);
}
free(brackets.items);
fclose(file);
}
int main() {
const char* filename = "example.cpp"; // 替换为你需要检测的C++源文件名
checkBrackets(filename);
return 0;
}
```
请注意,这个代码片段假设输入文件只包含ASCII字符,并且文件路径有效。实际应用中可能需要处理更多边界情况。同时,`realloc()`函数在这里用于动态扩展栈空间,但在生产环境中,可能需要更健壮的内存管理策略。
阅读全文