Knowledge points
Exception Handling(try, catch and throw), polymorphic, string
Introduction
We are going to write a program to calculate a string with some simbols, say a simple calculator. You need to throw the exceptions whenever there is something wrong in the string. In this experiment, you will learn how to define exception classes in c++ and how to handle it. Eception handling is a powerful tool in c++.
In C++ programming, an exception is a problem that arises during the execution of a program. A C++ exception is a response to an exceptional circumstance that arises while a program is running, such as an attempt to divide by zero.
Exceptions provide a way to transfer control from one part of a program to another. C++ exception handling is built upon three keywords: try, catch, and throw.
throw: A program throws an exception when a problem shows up. This is done using a throw keyword.
catch: A program catches an exception with an exception handler at the place in a program where you want to handle the problem. The catch keyword indicates the catching of an exception.
try: A try block identifies a block of code for which particular exceptions will be activated. It's followed by one or more catch blocks.
Unfortunately, there is no "finally" keyword in C++, you can learn it in java.
Requirements
This calculator is such a simple one and it can do these things:
- It can only handle with numbers which is in [0, 9].
- It can only calculate plus and minus, say '+' and '-'.
Some legal input strings:
1+2+3
1+3-2
1+1
1
Some illegal input strings:
11+24
2*4
4/2
+1-3
-2-1
Now your job is to figure out this problem: calculate and get the result of the expression string if it's legal. Otherwise, throw the exact exception.
Here are some exceptions which are defined in Exception.hpp
Here is a diagram:
Exception: This is the base class.
ExpressionException: This is a base class indicates the generall exception in expression calculating.
IllegalSymbolException: This is a exception class inidicates illegal symbols. All symbols are illegal except '0', '1', '2', '3'.... '9', '+' and '-'.
MissingOperatorException: An operator is missing when we are calculating. For example: "11+2" -> "Missing operator between 1 and 1 (position 1 expects an operator) "
MissingOperandException: An operand is missing when we are calculating. For example: "1++2" -> "Missing operand between + and + (position 2 expects an operand)"
EmptyExpressionException: If the expression string is empty, this exception will be thrown.
#include "Exception.hpp"
#include "Calculator.hpp"
#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::endl;
using std::string;
int main() {
calculator c;
std::string str;
bool flag;
while (cin >> str) {
flag = false;
try {
cout << c.calculate(str) << endl;
} catch(EmptyExpressionException e) {
cout << e.what() << endl;
flag = true;
} catch(MissingOperatorException e) {
cout << e.what() << endl;
flag = true;
} catch(MissingOperandException e) {
cout << e.what() << endl;
flag = true;
} catch(IllegalSymbolException e) {
cout << e.what() << endl;
flag = true;
} catch(ExpressionException e) {
cout << e.what() << endl;
flag = true;
} catch(Exception e) {
// unhandled exception
throw e;
}
if (!flag) {
std::cout << "No exception happened!" << std::endl;
}
}
return 0;
}
#ifndef EXCEPTION_HPP_
#define EXCEPTION_HPP_
#include <sstream>
#include <string>
class Utils {
public:
static std::string int2String(int num) {
std::stringstream ss;
ss << num;
return ss.str();
}
};
class Exception {
public:
virtual const std::string what() const throw() { return "Exception occors"; };
};
class ExpressionException : public Exception {
public:
virtual const std::string what() const throw() {
return "ExpressionException";
}
};
class IllegalSymbolException : public ExpressionException {
private:
int position;
public:
IllegalSymbolException(int position) : position(position) {}
virtual const std::string what() const throw() {
return "IllegalSymbolException at position:" + Utils::int2String(position);
}
};
class MissingOperatorException : public ExpressionException {
private:
int position;
public:
MissingOperatorException(int position) : position(position) {}
virtual const std::string what() const throw() {
return "Expected operator at position:" + Utils::int2String(position);
}
};
class MissingOperandException : public ExpressionException {
private:
int position;
public:
MissingOperandException(int position) : position(position) {}
virtual const std::string what() const throw() {
return "Expected operand at position:" + Utils::int2String(position);
}
};
class EmptyExpressionException : public ExpressionException {
public:
EmptyExpressionException() {}
virtual const std::string what() const throw() {
return "The expression is empty";
}
};
#endif
My Answer:
#include"Exception.hpp"
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
class calculator {
public:
calculator() {}
int calculate(std::string b) {
char arr[100];
strncpy(arr, b.c_str(), 100);
int m = b.length();
if (m == 0) {
throw(EmptyExpressionException());
}
for (int i = 0; i < m; i++) {
if (i%2 == 0) {
if (arr[i] > '9' ||arr[i] < '0') {
if (arr[i] == '+' || arr[i] == '-') {
throw(MissingOperandException(i));
} else {
throw(IllegalSymbolException(i));
}
}
} else {
if (arr[i] != '+'&&arr[i] != '-') {
if (arr[i] <= '9'&&arr[i] >= '0') {
throw(MissingOperatorException(i));
} else {
throw(IllegalSymbolException(i));
}
}
}
}
if (arr[m-1] == '+'||arr[m-1] == '-') { //排除尾数为操作数
throw(MissingOperandException(m));
}
int n = 0;
n += arr[0]-'0';
for (int k = 1; k < m-1; k += 2) { //求结果
if (arr[k] == '+') {
n += arr[k+1]-'0';
} else {
n -= arr[k+1]-'0';
}
}
return n;
}
};