【问题描述】
编写一程序检查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】
(){()}
本人语文理解能力比较差,在老师和同学的帮助下才勉勉强强读懂了题(wwww~
#include <stdio.h>
#include <string.h>
#define M 200
typedef struct node{
char ch;
int line;
}Node;
int main()
{
struct node STACK[M];
FILE *fp;
char s[201],c[201];
int flag=0,len,line=0,i,top=-1,j=0,temp;
fp=fopen("example.c","r");
while(fgets(s,200,fp)!=NULL)
{
line++;
len=strlen(s);
if(flag==1)//多行注释:flag为1,说明在这一行之前的几行里有/*,此处是为了找到多行注释的代码。
{
for(i=0;i<len;i++)
{
if(s[i]=='*'&&s[i+1]=='/')
{
flag=0;
i=i+2;
break;
}
}
}
else
{
i=0;//初始化为0,如果之前有过寻找*/则不用初始化,因为要在*/后面接着找。
}
for(;i<len;i++)
{
if(s[i]=='\n')
{
break;
}
else if(s[i]=='/')
{//又分两种情况
if(s[i+1]=='/')
{
break;//即读到//,直接跳出循环
}
else if(s[i+1]=='*')
{//必须要找到对应的*/
for(i=i+2;i<len;i++)
{
if(s[i]=='*'&&s[i+1]=='/')
{
flag=0;
i=i+2;
break;
}
}
if(i>=len)//这行行没找到对应的*/,跳出循环,继续看下一行
{
break;
}
}
}
else if(s[i]=='"')
{//对于引号,即字符常量、字符串常量的处理
for(i=i+1;i<len;i++)
{
if(s[i]=='"')
{
break;
}
}
}
else if(s[i]=='('||s[i]=='{')
{//入栈
c[j]=s[i];
j++;
top++;
STACK[top].ch=s[i];
STACK[top].line=line;
}
else if(s[i]==')'||s[i]=='}')
{//判断是否匹配,若匹配则出栈,不匹配则输出。
if(s[i]==')')
{
if(top==-1)
{//空栈
printf("without maching ')' at line %d\n",line);
return 0;
}
else
{
if(STACK[top].ch=='(')
{//匹配
c[j]=')';
j++;
top--;
}
else
{//虽然不匹配,但要进一步判断前面是否匹配
//例如:{(},应输出(
for(temp=top;temp>=0;temp--)
{
if(STACK[temp].ch=='(')
{
printf("without maching '%c' at line %d\n",STACK[top].ch,STACK[top].line);
return 0;
}
}
//找到不到对应匹配的括号
printf("without maching ')' at line %d\n",line);
return 0;
}
}
}
else
{
if(top==-1)
{
printf("without maching '}' at line %d\n",line);
return 0;
}
else
{
if(STACK[top].ch=='{')
{
c[j]='}';
j++;
top--;
}
else
{
for(temp=top;temp>=0;temp--)
{
if(STACK[temp].ch=='{')
{
printf("without maching '%c' at line %d\n",STACK[top].ch,STACK[top].line);
return 0;
}
}
printf("without maching '}' at line %d\n",line);
return 0;
}
}
}
}
}
//重置s
memset(s,'0',200);
}
//最后再判断栈是否为空,不为空则输出
c[j]='\0';
if(top!=-1)
{
do
{
printf("without maching '%c' at line %d\n",STACK[top].ch,STACK[top].line);
return 0;
}while(--top!=-1);
}
else if(top==-1)
{//全部匹配,则输出括号序列
printf("%s",c);
}
return 0;
}
要说的都写在代码注释里了。最后,因为教材上提供了本题的核心思路,所以写起来相对容易,较难的地方在于不同层级的逻辑关系比较复杂,嵌套比较多。