BUAA_数据结构_4TH_C程序括号匹配检查
题目描述:
编写一程序检查C源程序文件中{}、()等括号是否匹配,并输出第一个检测到的不匹配的括号及所对应括号所在的行号(程序中只有一个括号不匹配)。
注意:
1.除了括号可能不匹配外,输入的C源程序无其它语法错误。
2.字符常量、字符串常量及注释中括号不应被处理,注释包括单行注释//和多行/* */注释
3.字符常量和字符串常量中不包含转义字符’和";
4.程序中出现有意义括号的个数不超过200个;
不匹配判断规则:
1.当检测的程序括号为’{‘时,若其前序尚未匹配的括号为’(‘时,输出该’(‘左括号及所在行号;
2.当遇到一个不匹配的右括号’)‘或’}'时,输出该右括号及所在行号;
3.当程序处理完毕时,还存在不匹配的左括号时,输出该左括号及所在行号。
输入形式
打开当前目录下文件example.c,查询其括号是否匹配。该文件中每行字符数不超过200。
输出形式
若存在括号不匹配时,应输出首先能判断出现不匹配的括号及其所在的行号。当出现括号不匹配时,按下面要求输出相关信息:
without maching at line
其中为‘{’, ‘}’, ‘(’, ‘)’等符号,为该符号所在的行号。
若整个程序括号匹配,则按下面所示顺序输出括号匹配情况,中间没有空格。
(){(()){}}
参考代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define maxN 2000
char line[maxN+10];
char result[maxN+10];
int pos_res;
char stack[maxN+10];
int pos;
int stack_line[maxN];
int pos_line;
char t1[10]="//";
char t2[10]="/*";
char t3[10]="*/";
char temp1[maxN+10];
char temp2[maxN+10];
int handler(char s[],int num_line);
int begin_index(char s[], char t[]);
void quotation_handler(char s[]);
int tool_handler(char s[],int num_line);
int is_empty();
int is_full();
void push(char x);
char look();
char pop();
void push_line(int x);
int pop_line();
int main()
{
pos=-1;
pos_line=-1;
pos_res=0;
FILE *in;
in=fopen("example.c","r");
int num_line=0;
while((fgets(line,1024,in)!=NULL)){
num_line++;
int x=handler(line,num_line);
if(x==-1){//have /**/
while(1){
fgets(line,1024,in);
num_line++;
int mul_pos=begin_index(line,t3);
if(mul_pos!=-1){
line[mul_pos]='\0';
x=handler(line,num_line);
break;
}
}
}
else if(x==1) {
return 0;
}
}
if(!is_empty()){
char temp_last=pop();
int temp_last_line=pop_line();
printf("without maching \'%c\' at line %d",temp_last,temp_last_line);
return 0;
}
printf("%s",result);
return 0;
}
int handler(char s[],int num_line)
{
int len=strlen(s);
int single_pos=begin_index(s,t1);
int mul_pos=begin_index(s,t2);
int res_mul=1;
//printf("%d %d\n",single_pos,mul_pos);
if(single_pos!=-1&&mul_pos==-1){
s[single_pos]='\0';
}
else if(single_pos==-1&&mul_pos!=-1){
int mul_pos_other=begin_index(s,t3);
if(mul_pos_other==-1){
s[mul_pos]='\0';
res_mul=-1;
}
else{
memset(temp1,'\0',sizeof(temp1));
memset(temp2,'\0',sizeof(temp2));
strncpy(temp1,s,mul_pos);
strncpy(temp2,s+mul_pos_other+2,len-2-mul_pos_other);
strcat(temp1,temp2);
memset(s,'\0',sizeof(s));
strcpy(s,temp1);
}
}
else if(single_pos!=-1&&mul_pos!=-1){
int mini_pos=single_pos<mul_pos?single_pos:mul_pos;
if(mini_pos==single_pos){
s[single_pos]='\0';
}else{
int mul_pos_other=begin_index(s,t3);
if(mul_pos_other==-1){
s[mul_pos]='\0';
res_mul=-1;
}
else{
memset(temp1,'\0',sizeof(temp1));
memset(temp2,'\0',sizeof(temp2));
strncpy(temp1,s,mul_pos);
strncpy(temp2,s+mul_pos_other+2,len-2-mul_pos_other);
strcat(temp1,temp2);
memset(s,'\0',sizeof(s));
strcpy(s,temp1);
}
}
}
quotation_handler(s);
if(res_mul==-1){
int x=tool_handler(s,num_line);
if(x==1) return 1;
else return -1;
}
return tool_handler(s,num_line);
}
int begin_index(char s[], char t[])
{
int i,j,k;
for(i=0;s[i]!='\0';i++){
for(j=i,k=0;t[k]!='\0'&&s[j]==t[k];j++,k++){
;
}
if(t[k]=='\0')
return i;
}
return -1;
}
void quotation_handler(char s[])
{
memset(temp1,'\0',sizeof(temp1));
memset(temp2,'\0',sizeof(temp2));
int len=strlen(s);
int start_pos;
int end_pos;
for(int i=0;i<len;i++){
if(s[i]=='\"'){
start_pos=i;
for(i+=1;i<len;i++){
if(s[i]=='\"'){
end_pos=i;
strncpy(temp1,s,start_pos);
strncpy(temp2,s+end_pos+1,len-1-end_pos);
strcat(temp1,temp2);
memset(s,'\0',sizeof(s));
strcpy(s,temp1);
break;
}
}
quotation_handler(s);
break;
}
if(s[i]=='\''){
start_pos=i;
for(;i<len;i++){
if(s[i]=='\''){
end_pos=i;
strncpy(temp1,s,start_pos);
strncpy(temp2,s+end_pos+1,len-1-end_pos);
strcat(temp1,temp2);
memset(s,'\0',sizeof(s));
strcpy(s,temp1);
break;
}
}
quotation_handler(s);
break;
}
}
}
int tool_handler(char s[],int num_line)
{
int len=strlen(s);
for(int i=0;i<len;i++){
//printf("line:%d:%s-------------\n",num_line,stack);
if(s[i]=='{'){
if(!is_empty()){
char x=look();
if(x=='('){
int line_res=pop_line();
printf("without maching \'%c\' at line %d",x,line_res);
return 1;
}else{
push('{');
push_line(num_line);
}
}
else{
push('{');
push_line(num_line);
}
}
else if(s[i]=='('){
push('(');
push_line(num_line);
}
else if(s[i]=='}'){
if(is_empty()){
printf("without maching \'}\' at line %d",num_line);
return 1;
}
else{
char x=pop();
result[pos_res++]='}';
int temp_line=pop_line();
if(x!='{'){
printf("without maching \'}\' at line %d",num_line);
return 1;
}
}
}
else if(s[i]==')'){
if(is_empty()){
printf("without maching \')\' at line %d",num_line);
return 1;
}
else{
char x=pop();
result[pos_res++]=')';
int temp_line=pop_line();
if(x!='('){
printf("without maching \')\' at line %d",num_line);
return 1;
}
}
}
}
return 0;
}
int is_empty()
{
if(pos==-1){
return 1;
}else{
return 0;
}
}
int is_full()
{
if(pos==maxN-1){
return 1;
}else{
return 0;
}
}
void push(char x)
{
if(is_full()) printf("boom!");
else{
result[pos_res++]=x;
stack[++pos]=x;
}
}
char look()
{
return stack[pos];
}
char pop()
{
char res=stack[pos];
stack[pos]='\0';
pos--;
return res;
}
void push_line(int x)
{
stack_line[++pos_line]=x;
}
int pop_line()
{
int res=stack_line[pos_line];
stack_line[pos_line]='\0';
pos_line--;
return res;
}
选择了一种比较麻烦的方法
代码量比较大但是思路应该是比较清晰的
有问题或bug欢迎私戳/评论