#include #include "roman.h" istream& getRomanNumeral(istream &i, char buf[]) { char c; int index = 0; buf[index] = '\0'; while(!index && i.get(c)) { switch(c) { case 'I': case 'V': case 'X': case 'L': case 'C': case 'D': case 'M': buf[index++] = c; break; } } // if index is 0, no valid characters were found and eof was reached. if(!index) return i; int valid = 1; while(i.get(c) && valid && index < MAX_ROMAN_LEN) { switch(c) { case 'I': case 'V': case 'X': case 'L': case 'C': case 'D': case 'M': buf[index++] = c; break; default: valid = 0; i.putback(c); } } if(index == MAX_ROMAN_LEN) { // we were about to write off the end buf[0] = '\0'; // specs demand the empty string be written while(valid) { // now eat up all remaining roman numeral characters switch(c) { case 'I': case 'V': case 'X': case 'L': case 'C': case 'D': case 'M': i.get(c); break; default: i.putback(c); valid = 0; } } } else { // we either reached eof, or the end of the valid string buf[index] = '\0'; } return i; } int thousands(const char roman[], int index, int& sum) { while(roman[index] == 'M') { sum += 1000; index++; } // sum is now the sum of all M's // index is the first non-M character return index; } int oneFiveTen(const char roman[], int index, int& sum, char one, char five, char ten, int multiplier) { if(roman[index] == one) { // first character is the one character. // check for four or nine index++; if(roman[index] == ten) { sum += (9 * multiplier) ; return index + 1; } else if (roman[index] == five) { sum += (4 * multiplier); return index + 1; } else { sum += multiplier; } } else if(roman[index] == five) { // first character is the five character index++; sum += (5 * multiplier); } // there should be nothing but ones for the remainder of this decimal digit while(roman[index] == one) { sum += multiplier; index++; } // sum is now correctly accumulated for this digit // index should be the first character of the next decimal digit // if the input is well formed return index; } int hundreds(const char roman[], int index, int& sum) { return oneFiveTen(roman, index, sum, 'C', 'D', 'M', 100); } int tens(const char roman[], int index, int& sum) { return oneFiveTen(roman, index, sum, 'X', 'L', 'C', 10); } int ones(const char roman[], int index, int& sum) { return oneFiveTen(roman, index, sum, 'I', 'V', 'X', 1); } int romanToInt(const char roman[]) { int index = 0, sum = 0; index = thousands(roman, index, sum); index = hundreds(roman, index, sum); index = tens(roman, index, sum); index = ones(roman, index, sum); if(roman[index]) return -1; // the whole string was not consumed so there // was an error return sum; }