练习3.18】用下列语言编写检测平衡符号的程序
a.Pascal ( begin/end, ( ), [ ], { } )。
b.C语言( /* */, ( ), [ ], { })。
c.解释如何打印出错信息
用c++实现,思路差不多,按书上的思路,碰见平衡符号起始标准压入栈中,碰见平衡符号结束标志弹出栈,如果弹出的不匹配,中断循环提前跳出报错“不匹配”, 碰见其他符号跳过,当压入栈中的元素都弹出时,匹配成功。、
checkBalanceSymbol.h
#pragma once
#include <stack>
#include <fstream>
#include <string>
//练习3.21新增,检查语言平衡符号
void checklang(std::ifstream &ifile);
checkBalanceSymbol.cpp
#include <iostream>
#include "checkBalanceSymbol.h"
void checklang(std::ifstream &ifile)
{
if (ifile)
{
std::stack<char> check;
//避免空栈导致抛出异常
check.push('!');
//string testall("()[]{}*/");
std::string pushin("([{*");
std::string popout(")]}/");
char prev = '\0';
char curr;
ifile >> curr;
while (!ifile.eof())
{
//如果栈首为注释符,则除非出现反注释,否则全部跳过
if (check.top() == '/')
{
if (prev == '*' && curr == '/')
check.pop();
}
else
{
//如果检测到开始标志
if (pushin.find(curr) != std::string::npos)
{
//如果是单对应符则直接入栈
if (curr != '*')
check.push(curr);
//如果是注释则入栈
else if (prev == '/')
check.push('/');
//否则,必然有curr == '*', 而prev != '/',不作处理继续运行
}
//如果检测到结束标志
else if (popout.find(curr) != std::string::npos)
{
//如果是三个单对应符号
//则可对应即弹出,不可对应则跳出并将报错
if (curr == ')')
{
if (check.top() == '(')
check.pop();
else
break;
}
else if (curr == ']')
{
if (check.top() == '[')
check.pop();
else
break;
}
else if (curr == '}')
{
if (check.top() == '{')
check.pop();
else
break;
}
//如果是反注释
else if (prev == '*')
{
if (check.top() == '/')
check.pop();
else
break;
}
//如果不是反注释则不做任何操作
}
}
//读取下一个字符
prev = curr;
ifile >> curr;
}
//如果curr未到达文件尾
//必然是因为错误的单符号对应而跳出循环
if (!ifile.eof())
{
std::cout << curr << " and " << check.top() << std::endl;
std::cout << "Incorrect pop!" <<std:: endl;
}
//如果到达文件尾后,栈首不是初始的'!'
//必有后半平衡符缺失
else if (check.top() != '!')
std::cout << "Missing ending!" << std::endl;
else
std::cout << "Success" << std::endl;
while(!check.empty()) //释放空间
check.pop();
}
else
std::cout << "Cannot find stream!" <<std:: endl;
}
main.cpp
#include <iostream>
#include "checkBalanceSymbol.h"
using namespace std;
int main()
{
ifstream infile("Text.txt");
checklang(infile);
return 0;
}