Roman numerals enum

I was just working on a short code that converts Roman numerals to arabic numbers. I use enum to record the values so I can easilly use logical operators for exception handling. The exceptions, btw, get kind of hairy. I think I caught most errors, but I didn't catch issues like IIII or MCCCCCCC; those will equal 4 and 1700 respectively. I'm really just looking for ideas to improve the current code.


#include<iostream>
using namespace std;

class IVX{};//checks that preceding values are not less than X
class CCD{};//checks that
class ten{};//catch that preceding number is 10 times greater than new char
class VL{};//catch if V precedes L or L precedes C
class pre2new{};//catch if pre2 == new such as IXI
class LL{};//Catch if add LL or DD twice
enum Roman {Not = 0, I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000};
Roman change(char ch);//convert char to Roman enum
void checkvalues(Roman p, Roman p2, Roman n);//exception handling

int main()
{
cout << "Type in Roman numerals (I, V, X, L, C, D, M) to get arabic number: ";
char ch = ' ';
int n = 0;
Roman pre2_value = Not;//records value two time before new
Roman pre_value = Not;//records previous value
Roman new_value = Not;//is the new value
while(cin.get(ch) && ch != '\n')//get ch until \n
{
try{

new_value = change(ch);

if((pre_value < new_value))
n += new_value-(pre_value*2);//if less than subtract pre from n and also subtract previously added pre

else
n += new_value;//add new value to whole

if(pre_value != Not)//after first loop to avoid logical errors in exceptions
{checkvalues(pre_value, pre2_value, new_value);}
pre2_value = pre_value;//set pre to pre2
pre_value = new_value;//set new to pre

}
catch(CCD){cout << "Error:Cannot subtract more than one numeral!"; return 0;}
catch(IVX){cout << "Error: Cannot subtract two lesser values."; return 0;}
catch(ten){cout << "Error: Preceding value cannot be 10 times less than new value."; return 0;}
catch(VL){cout << "Error: L cannot precede C and V cannot precede L."; return 0;}
catch(pre2new){cout << "Error: Cannot add and subtract an equal value from a larger number e.g. IXI."; return 0;}
catch(LL){cout << "Error: Cannot add L or D to itself."; return 0;}
}
cout << "Your value is: " << n;
}


//convert char to Roman type
Roman change(char ch)
{
Roman new_ch = Not;
if(ch == 'M' || ch == 'm')
new_ch = M;
else if(ch == 'C' || ch == 'c')
new_ch = C;
else if(ch == 'D' || ch=='d')
new_ch = D;
else if(ch == 'L' || ch=='l')
new_ch = L;
else if(ch == 'X' || ch=='x')
new_ch = X;
else if(ch == 'V' || ch=='v')
new_ch = V;
else if(ch == 'I' || ch=='i')
new_ch = I;
else if(new_ch == Not)
{cout << ch << " is not a roman numeral. " << endl; return Not;}
return new_ch;
}





//Exceptions
void checkvalues(Roman pre_value, Roman pre2_value, Roman new_value)
{

if(pre2_value == new_value && (pre_value != new_value) && (pre_value>new_value))//check for CDC but allow MCM
throw pre2new();

if(pre2_value == Not)
pre2_value = new_value;//set pre2_value to new_value to avoid logical errors where pre2<pre and so on

if(pre_value*10<new_value)//the preceding variable must be 10 times less than new value so IC is illegal but XC is accepted
throw ten();

if((pre2_value == pre_value) && (new_value>pre_value))//Can't subtract to equal values
throw CCD();

if(((pre2_value < pre_value) && (pre_value < new_value)) || ((pre2_value > pre_value)) && (pre2_value < new_value))
throw IVX();//can't subtract two distinct values that are less than larger value

if((pre_value == V && new_value == L) || (pre_value == L && new_value == C))
throw VL();//Can't subract V from L of L from C

if((pre_value == L && new_value == L) || (pre_value == D && new_value == D))
throw LL();//Can't Add L to L or D to D
}









Topic archived. No new replies allowed.