Here are the requirements and the assumptions:
read and display the original expression
convert each Roman numeral to its Arabic equivalent
compute the result
display the expression with Arabic numbers
display the result as an Arabic number
Assumptions
All data will be read from a data file via Linux redirection.
All expressions in the data file will be valid (valid operators and Roman numerals).
The Roman numerals and operator in each expression may be separated by 0 or more blanks.
Each line in the data file will be terminated by a linefeed (endl).
This is my test data:
I+XIX
XXIII / V
CCCL +MMI
XIV- XXXV
VI * IX
And finally, this is my code:
#include <iostream> #include <iomanip> using namespace std; void stringToDecimal(char expression[], int &deciRes, const int d[], const char r[]); void performOperation(int, int, char, int &); bool checkForErrors(int, int, char, int); void decimalToString(int, char romRes[], const int d[], const char r[]); void outputEquation(char e1[], char e2[], int exDec1, int exDec2, char oper, int dResult, char rResult[]); string e1; string e2 = "0"; string oper; int add1; int sub1; int mul1; int div1; int len1; int len2; int pos; const int decimal[8] = {0, 1, 5, 10, 50, 100, 500, 1000}; const char roman[8] = {'O', 'I', 'V', 'X', 'L', 'C', 'D', 'M'}; int main() { char expression1[19], expression2[19], romanResult[19] = {0}, operation; int decimalEx1 = 0, decimalEx2 = 0, decimalResult; bool valid; cin >> e1; while (cin) { add1 = e1.find('+'); sub1 = e1.find('-'); mul1 = e1.find('*'); div1 = e1.find('/'); if((add1 > -1) || (sub1 > -1) || (mul1 > -1) || (div1 > -1)) { len1 = e1.length(); if(add1 > -1) pos = add1; else if(sub1 > -1) pos = sub1; else if(mul1 > -1) pos = mul1; else if(div1 > -1) pos = div1; if(len1 > (pos+1)) { if(add1 > -1) { oper = '+'; e2 = e1.substr((add1+1),(e1.length()-add1)); e1 = e1.substr(0,(e1.length()-(e1.length()-(add1)))); } else if(sub1 > -1) { oper = '-'; e2 = e1.substr((sub1+1),(e1.length()-sub1)); e1 = e1.substr(0,(e1.length()-(e1.length()-(sub1)))); } else if(mul1 > -1) { oper = '*'; e2 = e1.substr((mul1+1),(e1.length()-mul1)); e1 = e1.substr(0,(e1.length()-(e1.length()-(mul1)))); } else if(div1 > -1) { oper = '/'; e2 = e1.substr((div1+1),(e1.length()-div1)); e1 = e1.substr(0,(e1.length()-(e1.length()-(div1)))); } } else { e1 = e1.substr(0, (len1-1)); if(add1 > -1) oper = '+'; else if(sub1 > -1) oper = '-'; else if(mul1 > -1) oper = '*'; else if(mul1 > -1) oper = '*'; else if(div1 > -1) oper = '/'; } } else cin >> oper; len2 = oper.length(); if(len2 != 1) { e2 = oper.substr(1, (len2-1)); oper = oper.substr(0, 1); } else if((len2 == 1) && (e2 == "0")) { cin >> e2; } valid = false; stringToDecimal(expression1, decimalEx1, decimal, roman); stringToDecimal(expression2, decimalEx2, decimal, roman); performOperation(decimalEx1, decimalEx2, operation, decimalResult); valid = checkForErrors(decimalEx1, decimalEx2, operation, decimalResult); if (valid == true) { decimalToString(decimalResult, romanResult, decimal, roman); outputEquation(expression1, expression2, decimalEx1, decimalEx2, operation, decimalResult, romanResult); } } cout << "Quitting!!!" << endl; return 0; } void stringToDecimal(char expression[], int &deciRes, const int decimal[], const char roman[]) { int i, n, j; n = strlen(expression); deciRes = 0; for(i=0; i < n; i++) { for(j=1; j < 8; j++) { if(expression[i] == roman[j]) deciRes += decimal[j]; } } } void performOperation(int e1, int e2, char oper, int &deciRes) { switch (oper) { case '+': deciRes = e1 + e2; break; case '-': deciRes = e1 - e2; break; case '*': deciRes = e1 * e2; break; case '/': deciRes = e1 / e2; break; default: deciRes = e1 % e2; } } bool checkForErrors(int deciEx1, int deciEx2, char oper, int deciRes) { if (oper != '+' && oper != '-' && oper != '*' && oper != '/' && oper != '%') { cout << "Error. Invalid operation" << endl; return false; } else if(((deciEx1 == deciEx2) && oper =='-') || deciRes == 0) { cout << "Error. Result can not be zero" << endl; return false; } else return true; } void decimalToString(int decAns, char romAns[], const int d[], const char r[]) { int i, j=0, n, count=0; // Reset values in romanResult[] n= strlen(romAns); // if taken out, ex2 wont show; length romAns not defined for(i=0; i < n; i++) romAns[i] = 0; // End for(i=7; i > 0; i--) { if( decAns >= d[i]) { count = decAns / d[i]; decAns = decAns - (count * d[i]); while (count != 0) { romAns[j] = r[i]; j++; count--; } } } } void outputEquation(char e1[], char e2[], int exDec1, int exDec2, char oper, int dResult, char rResult[]) { cout << e1 << " " << oper << " " << e2 << " " << " = " << " " << exDec1 << " " << oper << " " << exDec2 << " " << "=" << " " << dResult << " (" << rResult << ") " << endl;