【Weiss】【第03章】练习3.18:检查平衡符号
【练习3.18】用下列语言编写检测平衡符号的程序
a.Pascal ( begin/end, ( ), [ ], { } )。
b.C语言( /* */, ( ), [ ], { })。
c.解释如何打印出错信息
Answer:
a和b本质是一样的,就写了b小题即C语言的检测。
基本思想就是用栈,除了注释符号有一点点麻烦要查看连续两个字符,其它的几组都是很轻松愉快。
具体的细节都放到注释里了,所以在文章上没必要说太多。
这题测试代码就不放了,基本就是自己拿个文本文件改来改去,在main函数里面就三行,总之是实测是能通过的。
1 //练习3.18新增,检查语言平衡符号 2 void checklang(ifstream &ifile) 3 { 4 if (ifile) 5 { 6 Stack<char> check; 7 //避免空栈导致getfirst()抛出异常 8 check.push('!'); 9 //string testall("()[]{}*/"); 10 string pushin("([{*"); 11 string popout(")]}/"); 12 char prev = '\0'; 13 char curr; 14 ifile >> curr; 15 while (!ifile.eof()) 16 { 17 //如果栈首为注释符,则除非出现反注释,否则全部跳过 18 if (check.getfirst() == '/') 19 { 20 if (prev == '*' && curr == '/') 21 check.pop(); 22 } 23 else 24 { 25 //如果检测到开始标志 26 if (pushin.find(curr) != string::npos) 27 { 28 //如果是单对应符则直接入栈 29 if (curr != '*') 30 check.push(curr); 31 //如果是注释则入栈 32 else if (prev == '/') 33 check.push('/'); 34 //否则,必然有curr == '*', 而prev != '/',不作处理继续运行 35 } 36 //如果检测到结束标志 37 else if (popout.find(curr) != string::npos) 38 { 39 //如果是三个单对应符号 40 //则可对应即弹出,不可对应则跳出并将报错 41 if (curr == ')') 42 { 43 if (check.getfirst() == '(') 44 check.pop(); 45 else 46 break; 47 } 48 else if (curr == ']') 49 { 50 if (check.getfirst() == '[') 51 check.pop(); 52 else 53 break; 54 } 55 else if (curr == '}') 56 { 57 if (check.getfirst() == '{') 58 check.pop(); 59 else 60 break; 61 } 62 //如果是反注释 63 else if (prev == '*') 64 { 65 if (check.getfirst() == '/') 66 check.pop(); 67 else 68 break; 69 } 70 //如果不是反注释则不做任何操作 71 } 72 } 73 //读取下一个字符 74 prev = curr; 75 ifile >> curr; 76 } 77 //如果curr未到达文件尾 78 //必然是因为错误的单符号对应而跳出循环 79 if (!ifile.eof()) 80 { 81 cout << curr << " and " << check.getfirst() << endl; 82 cout << "Incorrect pop!" << endl; 83 } 84 //如果到达文件尾后,栈首不是初始的'!' 85 //必有后半平衡符缺失 86 else if (check.getfirst() != '!') 87 cout << "Missing ending!" << endl; 88 else 89 cout << "Success" << endl; 90 check.clear(); 91 } 92 else 93 cout << "Cannot find stream!" << endl; 94 }