【问题描述】
编写一程序检查C源程序文件中{}、()等括号是否匹配,并输出第一个检测到的不匹配的括号及所对应括号所在的行号(程序中只有一个括号不匹配)。
注意:
1.除了括号可能不匹配外,输入的C源程序无其它语法错误。
2.字符常量、字符串常量及注释中括号不应被处理,注释包括单行注释//和多行/* */注释
3.字符常量和字符串常量中不包含转义字符\'和\";
4.程序中出现有意义括号的个数不超过200个;
不匹配判断规则:
1.当检测的程序括号为'{'时,若其前序尚未匹配的括号为'('时,输出该'('左括号及所在行号;
2.当遇到一个不匹配的右括号')'或'}'时,输出该右括号及所在行号;
3.当程序处理完毕时,还存在不匹配的左括号时,输出该左括号及所在行号。
【输入形式】
打开当前目录下文件example.c,查询其括号是否匹配。该文件中每行字符数不超过200。
【输出形式】
若存在括号不匹配时,应输出首先能判断出现不匹配的括号及其所在的行号。当出现括号不匹配时,按下面要求输出相关信息:
without maching <x> at line <n>
其中<x>为‘{’, ‘}’, ‘(’, ‘)’等符号,<n>为该符号所在的行号。
若整个程序括号匹配,则按下面所示顺序输出括号匹配情况,中间没有空格。
(){(()){}}
【样例输入1】
若当前目录下输入文件example.c中内容如下:
#include<stdio.h>
int main(){
printf("{ hello world }\n"); // }
)
【样例输出1】
without maching ')' at line 4
【样例输入2】
若当前目录下输入文件example.c中内容如下:
#include<stdio.h>
int main(){
printf("{ hello world }d\n"); /* }*/
【样例输出2】
without maching '{' at line 2
【样例输入3】
若当前目录下输入文件example.c中内容如下:
#include<stdio.h>
int main(){
printf("{ hello world }d\n"); /* }*/
}
【样例输出3】
(){()}
【样例说明】
样例1:在注释部分和字符串中的括号不考虑,在将程序处理之后得到的括号序列是(){()),遇到右括号时与最近的左括号匹配,发现最后一个小括号和大括号不匹配。
样例2:处理之后的括号序列是(){(),在最后缺少了右大括号,那么应该输出与之相对应的左括号不匹配。
【评分标准】
通过所有测试点得满分。
解题思路:因为题目要求我们判断括号的行数,因此我们要分行来读入,一个一个地判断是否是括号,将所有括号放入数组1中,将‘(’、‘{’放入数组2中,如果读入一个‘)’或‘}’,就在数组2中判断它的前一个括号是否匹配,如果匹配成功,就将匹配到的括号在数组2中删除,如果遇到其他特殊的字符就要特殊对待。
参考代码:
#include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <ctype.h> struct huohao { char kuo; int len; }allhao[300],skuohao[300]; char shuru[300]; int main() { int i=0,j=0,l=0,k=0,n=0,find=0,x=0,mark=0,y,flag=0;//find表示是否已经找到不匹配的括号 FILE *in; in=fopen("example.c","r");//打开文件 while(fgets(shuru,201,in)!=NULL&&find==0)//分行读入 { l++; n=strlen(shuru); for(k=0;k<n;k++) { if(shuru[k]=='(') { allhao[i].kuo=shuru[k]; allhao[i].len=l; skuohao[j].kuo=shuru[k]; skuohao[j].len=l; i++; j++; }//直接存入 else if(shuru[k]=='{') { if(j!=0&&skuohao[j-1].kuo=='(') { printf("without maching '(' at line %d\n",skuohao[j-1].len); find=1; break; }//()内部不能出现{} else { allhao[i].kuo=shuru[k]; allhao[i].len=l; skuohao[j].kuo=shuru[k]; skuohao[j].len=l; i++; j++; }//直接存入 } else if(shuru[k]==')') { allhao[i].kuo=shuru[k]; allhao[i].len=l; i++;//首先存入 if(j==0||skuohao[j-1].kuo!='(') { printf("without maching ')' at line %d\n",l); find=1; break; }//在skuohao这个数组中进行匹配 else { skuohao[j-1].kuo='\0'; skuohao[j-1].len=0; j--; }//匹配到就删除 } else if(shuru[k]=='}') { allhao[i].kuo=shuru[k]; allhao[i].len=l; i++; if(j==0||skuohao[j-1].kuo!='{') { printf("without maching '}' at line %d\n",l); find=1; break; } else { skuohao[j-1].kuo='\0'; skuohao[j-1].len=0; j--; } }//同上 else if(shuru[k]=='/'&&shuru[k+1]=='/') break;//读到// else if(shuru[k]=='/'&&shuru[k+1]=='*') { for(x=k+2,mark=0;x<n;x++) { if(shuru[x]=='*'&&shuru[x+1]=='/') { mark=1; break; } } while(mark==0) { for(y=0;y<201;y++) shuru[y]='\0'; fgets(shuru,201,in); l++; n=strlen(shuru); for(x=0;x<n;x++) { if(shuru[x]=='*'&&shuru[x+1]=='/') { mark=1; break; } } } k=x+1; }//读到/**/的情况 else if(shuru[k]=='"') { for(x=k+1;x<n;x++) { if(shuru[x]=='\\') x++; else if(shuru[x]=='"') break; } k=x; }//读到“再向后寻找” else if(shuru[k]=='\'') { for(x=k+1;x<n;x++) { if(shuru[x]=='\\') x++; else if(shuru[x]=='\'') break; } k=x; }//读到/' } for(y=0;y<200;y++) shuru[y]='\0';//将shuru删除 } if(find==0&&j==0) { for(j=0;j<i;j++) printf("%c",allhao[j].kuo); }//如果匹配全部成功,则输出括号 else if(find==0&&j==1) printf("without maching '%c' at line %d\n",skuohao[j-1].kuo,skuohao[j-1].len);//如果最后还上下一个括号没有删除,则输出 fclose(in); }