Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //main******************************************************************************************************
- //cplusplus.com/forum/beginner/75558
- #include <iostream>
- #include "RomanInt.h"
- int main()
- {
- RomanInt RInt;
- do
- {
- std::cout << "Enter a roman numeral: ";
- std::cin >> RInt;
- }
- while (true);
- }
- //RomanInt.h************************************************************************************************
- #ifndef ROMANINT_H
- #define ROMANINT_H
- #include <string>
- #include <iostream>
- #include <cstdlib>
- #include <algorithm>
- class RomanInt
- {
- public:
- RomanInt (std::string RNum = "");
- void PrintRoman(int);
- private:
- void Convert (std::string RNum);
- int ValueOf (char RChar);
- bool IsValid (std::string RNum);
- friend std::istream& operator>> (std::istream& is, RomanInt& RInt);
- std::string RomanNumeral;
- int DecimalNumeral;
- };
- #endif
- //RomanInt.cpp**********************************************************************************************
- #include "RomanInt.h"
- RomanInt::RomanInt (std::string RNum) :
- RomanNumeral (RNum)
- {
- if (RNum != "") Convert (RNum);
- }
- void RomanInt::Convert (std::string RNum)
- {
- int DecimalNumeral = 0;
- bool isOdd = 0;
- int ValueL;
- int ValueR;
- for (unsigned int i = 0; i < RNum.length(); i++)
- {
- if (RNum.length() % 2 && i == 0) // is odd and first number
- {
- isOdd = 1;
- DecimalNumeral += ValueOf (RNum[0]);
- }
- else
- {
- ValueL = ValueOf (RNum[RNum.length() - i - 2 + isOdd]); //shortcut and easier on the eyes
- ValueR = ValueOf (RNum[RNum.length() - i - 1 + isOdd]);
- if (ValueL < ValueR) DecimalNumeral += (ValueR - ValueL);
- else DecimalNumeral += (ValueL + ValueR);
- i++; //do it in groups of 2
- }
- }
- std::cout << RNum << " = " << DecimalNumeral << std::endl;
- }
- int RomanInt::ValueOf (char RChar)
- {
- switch (RChar)
- {
- case 'I': return 1;
- case 'V': return 5;
- case 'X': return 10;
- case 'L': return 50;
- case 'C': return 100;
- case 'D': return 500;
- case 'M': return 1000;
- default:
- std::cout << RChar << " should not be in the ValueOf function, something broke" << std::endl;
- exit (1); //terminate
- }
- return -10000; //shouldn't ever be called, but just in case some weird shit goes on.
- }
- void RomanInt::PrintRoman(int var)
- {
- if (var == 0) std::cout << RomanNumeral << std::endl; //why? don't ask me, part of the exercise
- else std::cout << DecimalNumeral << std::endl; //why? don't ask me, part of the exercise
- }
- bool RomanInt::IsValid (std::string RNum)
- {
- for (unsigned int i = 0; i < RNum.length(); i++)
- {
- if ( (RNum[i] != 'I' && RNum[i] != 'V' && RNum[i] != 'X' && RNum[i] != 'L' && RNum[i] != 'C' && RNum[i] != 'D' && RNum[i] != 'M'))
- return false; // only accept IVXLCDM
- else if ( (RNum.length() >= 4 && i <= RNum.length() - 4) && (RNum[i] == RNum[i+1]) && (RNum[i+1] == RNum[i+2]) && (RNum[i+2] == RNum[i+3]))
- return false; // no more than 3 of the same character in a row
- }
- return true;
- }
- std::istream& operator>> (std::istream& is, RomanInt& RInt)
- {
- std::string RNum;
- is >> RNum; //get input
- std::transform (RNum.begin(), RNum.end(), RNum.begin(), ::toupper); //fix lowercase
- if (RInt.IsValid (RNum)) //check we can convert it
- {
- RInt.RomanNumeral = RNum;
- RInt.Convert (RNum);
- }
- else std::cout << "Invalid Numeral " << RNum << " entered\n" << std::endl;
- return is;
- }
Advertisement
Add Comment
Please, Sign In to add comment