TDT4102, Spring 2009

Exercise 12

Deadline: 04.05.2009


The objective of this exercise:

General requirements:

Recommended reading:


Part 1: Handling exceptions within a program

Extend the program below by implementing exception handling.

The program reads two integers from cin, performs an integer division and prints out the quatient  (the result from the integer division).
If the input is correct the program works well, but there are differerent things that can cause errors:
  1. If the user enters a character or a string as divident, an error message is printed (but the program continues)
  2. If the user enters a character or a string as divisor, an error message is printed (but the program continues)
  3. If the user enters 0 as the divisor the result is a run-time error because of division by zero
Your assignement is to create a program that takes care of these situations by throwing and catching exceptions.
If an exception occurs in one of the function calls, the main-function should be able to catch this, print out an error message and terminate.
It is suffficient to use a string as the exception datatype in all cases. The string exceptions should indicate the error that has caused the exception: use a different string for the three above mentioned cases.
Note that exceptions should be thrown in the varius functions but caught in main().


#include <iostream>
#include <string>

using namespace std;

int readDividend();
int readDivisor();
int quotient(int dividend, int divisor);
void print(int result);

int main(){
    int dividend = readDividend();
    int divisor = readDivisor();
    int result = quotient(dividend, divisor);
    print(result);
    return 0;
}
int readDividend(){
    int dividend = 0;
    cout << "Enter the dividend: ";
    cin >> dividend;
    cout << endl;
    if (!cin){ //in case the input is not an integer cin will be in a fail state
        cout << "Illegal input" << endl;
    }
    return dividend;
}

int readDivisor(){
    int divisor = 0;
    cout << "Enter the divisor: ";
    cin >> divisor;
    cout << endl;
    if (!cin){ //in case the input is not an integer cin will be in a fail state
        cout << "Illegal input" << endl;
    }
    return divisor;
}

int quotient(int dividend, int divisor){
    return dividend/divisor;
}

void print(int result){
    cout << "Quotient = " << result << endl;
}


Example behaviour and output after implementing exception handling:

1) Legal input values:
Enter the dividend: 5
Enter the divisor: 2
Quotient = 2


2) Trying to use a string as dividend:
Enter the dividend: xxx
Exception: Illegal input for dividend
3) Trying to use a string as divisor:
Enter the dividend: 55
Enter the divisor: xxx
Exception: Illegal input for divisor


4) Trying to use 0 as divisor:
Enter the dividend: 555
Enter the divisor: 0
Exception: Cannot divide by zero



Part 2: Custom exception classes

A Triangle is a geometric figure with three sides. A triangle is valid only if the sum of any two of the sides is greater than the third side. Additionally, each side has to be a positive value larger than zero ( side > 0).
When you attempt to create a triangle, or change a side of a triangle, you need to ensure that these properties are not violated. If they are violated, exceptions should be thrown.
A partial implementation of the class is listed below but you need to create functions for validating the sides and throw exceptions if a user tries to create illegal triangles or change any sides to an illegal valua.  Use custom exception classes for this purpose.

A) Add member functions for validating the sides of a triangle (to test if sides are > 0 and test if any combination of two sides is greater than the third side). (These functions are only for validating values and should not throw exceptions directly).

B) Create a custom exception class called TriangleException for exceptions that should be thrown in case the sides do not make a triangle (if the sum of any of the two sides is not greater than the third side). This exception class has to inherit the logic_error exception class in <stdexcept> and should include member variables for all of the side values (and get-functions) . The the inherited function what() should return a text that indicates that the triangle properties are violated (use the constructor of the parent class to set the text that what() returns.

C) Create a custom exception class called NonPositiveSideException for exceptions that should be thrown in case a side is a non-positive value. This exceptions class  has to inherited the invalid_argument exception class in <stdexcept> and should include a member variable for the erronous value (and a get-function). The message returned from the what() function can e.g. be "Invalid side" (use the constructor of the parent class to set the text that what() returns.

D) Implement the set-functions in the Triangle class and the constructor Triangle(double, double, double). If the properties of a triangle is violated, these functions should throw an exception for the violation. It is best to test for non-positive values first.

E) Make some triangle instances i with legal and illegal values in the main-method and try out the different exceptions. Change the sides by the use of the set-functions to make sure that exceptions are thrown by these functions as well. Use different catch-blocks for different types of exceptions and make sure that the exception handling is working as intended. Print out the information that is available about the exception. Make sure that exceptions are thrown both by the constructor and  by the set-functions.



#include <iostream>
#include <cmath>
#include <stdexcept>

using namespace std;

class Triangle{
private:
    double side1;
    double side2;
    double side3;
public:
    Triangle(){side1 = side2 = side3 = 1;};
    Triangle(double, double, double);
    void setSide1(double);
    void setSide2(double);
    void setSide3(double);
    double getSide1(){return side1;};
    double getSide2(){return side2;};
    double getSide3(){return side3;};
    double getPerimeter(){
        return side1 + side2 + side3;
    }
    double getArea(){
        double s = getPerimeter() / 2;
        return sqrt(s * (s - side1) * (s - side2) * (s - side3));
    }
};