【问题描述】
编写一程序检查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);
}