#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <iostream>
//#include <stack>
// using namespace std;
const char FH[6] = {'(', '{', '[', ')', '}', ']'};
struct program
{
char x; //存该符号
int y; //存该符号对应的行
};
typedef struct
{
program sign[100000];
int top;
} stack;
stack fh;
void sini(stack *s)
{
s->top = -1;
}
int sempty(stack s)
{
return s.top <= -1;
}
/*int ssize(stack s)
{
return s.top + 1;
}*/
program stop(stack s)
{
return s.sign[s.top];
}
void spush(stack *s, program e)
{
s->sign[++s->top] = e;
}
void spop(stack *s)
{
s->top--;
}
bool chrek(stack *s)
{
if (sempty(*s))
return 1;
else
{
while (!sempty(*s))
{
program temp;
temp = stop(*s);
printf("%c有问题\t位于第%d行\n", temp.x, temp.y);
spop(s);
}
}
return 0;
}
int main()
{
while (1)
{
program wrang[2000]; //储存错误的反括号
int top_of_wrang = 0; // wrang数组的浮标
sini(&fh);
system("cls");
printf("输入1开始\n输入2退出\n请选择:");
char r;
int inputway;
while (1)
{
r = getchar();
if (!(r - '1'))
{
printf("请选择结束方式\n");
printf("输入\"1\"以三个连续回车结尾(程序没有三个连续的回车)\n");
printf("输入\"2\"两个连续\"@\"和一个回车结尾(程序没有两个连续的@)\n");
scanf("%d", &inputway);
printf("请输入不多于100000字符的程序:\n");
break;
}
if (!(r - '2'))
exit(0);
}
char c, buff1 = '\n', buff2 = '\0'; // buff1和buff2分别为前一个字符的缓存和倒数第二个字符的缓存
int hang = 0; //统计行数
short dy = 0;
short sy = 0; //统计每种引号数量
int A = 0, B = 0;
while (1)
{
c = getchar();
if (c == '/' && buff1 == '/') //考虑以“//”为格式的注释
while (c != '\n')
{
c = getchar();
}
if (c == '*' && buff1 == '/') //考虑以“/*...*/”为格式的注释
{
char buff;
while (c != '/' || buff != '*')
{
buff = c;
c = getchar();
if (buff == '\n')
printf("%d", ++hang); //统计行数并且自动标行
}
}
if (c == '\'') //考虑'buff1'作为ASCII码出现在程序中,常规程序''只会用于取ASCII码,所以后面没有再对单引号做匹配
{
int cnt = 0;
char buff = '\0'; //考虑 '\'' 这种情况
char buff_; //考虑 '\\' 这种情况
while (1)
{
buff_ = buff;
buff = c;
c = getchar();
// printf("%c\n", c);
cnt++;
if (cnt > 3)
{
// printf("'有问题\t位于第%d行\n", hang);
wrang[top_of_wrang].x = '\'';
wrang[top_of_wrang++].y = hang;
break;
}
if (c == '\'' && (buff != '\\' || (buff == '\\' && buff_ == '\\')))
{
break;
}
}
}
program a;
a.x = buff1;
a.y = hang - 1;
if (buff1 == '\n')
printf("%d", ++hang); //统计行数并且自动标行
for (int i = 0; i < 3; i++) //正括号入栈
{
if (buff1 == FH[i])
{
spush(&fh, a);
// cout << "%%%%%%%%%%%%%%%%%" << endl;
}
}
for (int i = 3; i < 6; i++) //配对反括号
{
if (buff1 == FH[i])
{
if (!sempty(fh) || FH[i - 3] == stop(fh).x) // stop()函数默认为调用时栈不为空,所以将!sempty()放最前
{
spop(&fh);
// cout << "@@@@@@@@@@@@@@@@@@@@" << endl;
}
else
wrang[top_of_wrang++] = a;
}
}
if (buff1 == '"' && buff2 != '\\')//双引号处理!!!!!由于使用单栈实现,目前程序有一个bug,是当出现例如prinf("'");时程序会判单引号错误!!!!!!
{
sy++;
sy %= 2;
if (sy % 2)
spush(&fh, a);
else if (!sempty(fh) || buff1 == stop(fh).x)
{
spop(&fh);
}
else
wrang[top_of_wrang++] = a;
}
if (inputway == 1 && c == '\n' && buff1 == '\n' && buff2 == '\n')
break;
if (inputway == 2 && c == '\n' && buff1 == '@' && buff2 == '@')
break;
buff2 = buff1;
buff1 = c;
}
printf("\n"); //美化格式
if (!chrek(&fh) || top_of_wrang)
{
for (int i = 0; i < top_of_wrang; i++)
printf("%c有问题\t\t\t位于第%d行\n", wrang[i].x, wrang[i].y);
getchar();
continue;
}
printf("程序分号括号没有问题\n");
getchar();
memset(fh.sign, 100000, 0);
}
return 0;
}
栈实现程序括号匹配器(C语言)
最新推荐文章于 2022-09-18 11:59:58 发布