Roman Numeral

i have a source code, so far i have whats listed below...i have 2 questions: the first is, for some reason and i cant figure out why, but when i run the program once, it works fine, but once i try to repeat it, it stores the answer in the first input and calculates the total w/ the 2nd.  Also, i also need it to convert the numbers back into roman numerals and im unsure of how i could do this...i cant use pointers and nothing too 'advanced'...any help would be greatly appreciated.  

this is my source code:

#include <iostream>
#include <cmath>
#include <string>
using namespace std;

void Roman (int&);
int Operation (int, int, char);

char YesNo;
int answer;
int first;
int second;
int amount;
char Number;

int main()

{
      do{
      {
     

     amount = 0;
     
     cout<<"Enter the first roman numeral"<<endl;
     Roman(first);
     cout<<"Enter the second roman numeral"<<endl;
     Roman(second);
     cout<<"Enter the (+) for Addition (-) for Subtraction, (*) for Multiplication, or (/) for Division"<<endl;
     cin.get(Number);
     Operation (first, second, Number);
     cout<<first<<" "<<Number<<" "<<second<<" is "<<Operation(first,second,Number)<<"."<<endl;
      
      
       cout << "Do you want to Repeat Process Y or N" << endl;
      cin >> YesNo;
}
      }      while ((YesNo =='y' || YesNo =='Y'));
     return 0;
}

void Roman (int& amount)
{
          char RN;
          cin.get(RN);

          while (RN != '\n')
          {
         
          if (RN == 'M')
               amount = amount + 1000;
          if (RN == 'D')
               amount = amount + 500;
          if (RN == 'C')
               amount = amount + 100;
          if (RN == 'L')
               amount = amount + 50;
          if (RN == 'X')
               amount = amount + 10;
          if (RN == 'V')
               amount = amount + 5;
          if (RN == 'I')
               amount = amount + 1;
              cin.get(RN);
          }
         
}
int Operation (int first, int second, char Number)
{
     if (Number == '+')
     {
          answer  = first + second;
     }
     if (Number == '-')
     {
          answer  = first - second;          
     }
     if (Number == '*')
     {
          answer  = first * second;
     }
       return answer;
}
Kal130Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

itsmeandnobodyelseCommented:
You should  avoid to use global variables but move them to the function where you need them.

int main()
{
    char YesNo;
    int answer;
    int first;
    int second;
     
    do
    {
             ...

>>>> void Roman (int& amount)

Better is

    int Roman()

where you would return the value entered by the user.

Note, you used 'int amount' as global variable and as an argument, what is bad (but isn't an error as the latter was used). The reason, why your variable increases in the second run is cause you never initialize it to 0.

int Roman ()
{
          int amount = 0;  // make a local variable *but* remove the global one
          char RN;
          cin.get(RN);

          while (RN != '\n')
          {
              switch(RN)
              {
                  case 'M':
                      amount = amount + 1000; break;
                  case 'C'':
                      amount = amount + 100; break;
                  case 'L':
                      amount = amount + 50; break;
                  case 'X':
                      amount = amount + 10; break;
                  case 'V':
                      amount = amount + 5; break;
                  case 'I':
                      amount = amount + 1; break;
                  default:
                      return -1;         // bad value
                }  
          }
          return amount;
}

Note, you didn't consider the case where numbers have to be subtracted rather than added as in IX == 9. Your result would be 11.

Regards, Alex
0
itsmeandnobodyelseCommented:
To build (and parse) roman numbers (M, D, C, L, X, V, I) you have to apply the following rules:

1. The composite number is build up in thousands, hundreds, tens and ones from left to right.
2. To build 900, 400, 90, 40, 9, 4 you have to precede the next number by one single
    C (M and D), X (C and L) or I (X and V).
3. You have to take the minimum notation if there are more than one possible


Samples:

 99     == XCIX (90 + 9) and not LXXXXVIIII (breaks rule 3) or IC (breaks rule 2) or LIL (breaks rule 2).
 2321 == MMCCCXXI and not  MDDCCDXXI (MDD breaks rule 3) (CCD  breaks rule 1 and rule 2)

Here is an attempt to consider these rules in function Roman.

Some comments:

I changed char input to char array input in order to be able to peek to the next char. Tell me, if you would be allowed to use std::string instead of char array.

I also moved user input to main function as Roman function should be free of I/O stuff (cause you could use it generally for transforming a Roman number to an integer).

Regards, Alex


int Roman ()
{
    int amount = 0;  // make a local variable *but* remove the global one
    char input[256];
   
    cin >> input;
    if (stricmp(input, "Q") == 0)
        return 0;
 
    char RP  = ' ';     // previous
    char RN  = '\0';    // current
    char RNN = '\0';    // next
   
    int expected  = 1000;
    int duplicate = 0;  
    for (int i = 0; i < strlen(input); ++i)
    {
        RP  = RN;
        RN  = input[i];
        RNN = input[i+1];
        if (RP == RN)
            duplicate++;
        else
            duplicate = 0;
        switch(RN)
        {
        case 'M':
            if (expected < 1000)
                return -2;
            amount += 1000;
            break;
        case 'D':
            if (expected < 500)
                return -2;
            if (duplicate)
                return -3;
            amount += 500;
            expected = 100;
            break;
        case 'C':
            if (expected < 100)
                return -2;
            if (duplicate > 2)
                return -3;
            if (duplicate == 0 && (RNN == 'M' || RNN == 'D'))
            {
                amount += (RNN == 'M')? 900 : 400;
                expected = 50;
                i++;
            }
            else
                amount += 100;
            if (expected > 100)
                expected = 100;
            break;
        case 'L':
            if (expected < 50)
                return -2;
            if (duplicate)
                return -3;
            amount += 50;
            expected = 10;
            break;
        case 'X':
            if (expected < 10)
                return -2;
            if (duplicate > 2)
                return -3;
            if (duplicate == 0 && (RNN == 'L' || RNN == 'C'))
            {
                amount += (RNN == 'C')? 90 : 40;
                expected = 5;
                i++;
            }
            else
                amount += 10;
            if (expected > 10)
                expected = 10;
            break;
        case 'V':
            if (expected < 5)
                return -2;
            if (duplicate)
                return -3;
            amount += 5;
            expected = 1;
            break;
            break;
        case 'I':
            if (expected < 1)
                return -2;
            if (duplicate > 2)
                return -3;
            if (duplicate == 0 && (RNN == 'V' || RNN == 'X'))
            {
                amount += (RNN == 'X')? 9 : 4;
                expected = 0;
                i++;
            }
            else
                amount += 1;
            if (expected > 1)
                expected = 1;
            break;
        default:
            return -1;         // bad value
        }  
    }
    return amount;
}

int Operation (int first, int second, char Number)
{
     int answer = -1;
     if (Number == '+')
     {
         answer  = first + second;
     }
     if (Number == '-')
     {
         answer  = first - second;          
     }
     if (Number == '*')
     {
         answer  = first * second;
     }
     return answer;
}


int main()
{
     char input[256];
     int first, second, result;
     while (true)
     {
        cout << "First Roman  [Q to quit] ==>  ";
        cin >> input;
        if (stricmp(input, "Q") == 0)
            return 0;
 
        first = Roman(input);
        cout << endl << "First = " << first << endl << endl;
        if (first <= 0)
            continue;

        cout << "Second Roman [Q to quit] ==>  ";
        cin >> input;
        if (stricmp(input, "Q") == 0)
            return 0;
 
        second = Roman(input);
        cout << endl << "Second = " << second << endl << endl;

        if (second <= 0)
            continue;
        cout<<"(+) Addition \n(-) Subtraction \n(*) Multiplication \n(/) Division \n(Q) Quit \n\nEnter Choice ==> ";
        cin >> input;      

        if (stricmp(input, "Q") == 0)
            return 0;

        result = Operation(first, second, input[0]);
        cout << endl << "result = " << result << endl << endl;
     }
     return 0;
}


0
Kal130Author Commented:
hey im sorry to note, that i dont have to put 4 like IV, it have to be IIII
same w/ the rest of them
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

Kal130Author Commented:
std:: string i tink would be better because we havent gotten in depth w/ char array
0
itsmeandnobodyelseCommented:
>>>> hey im sorry to note, that i dont have to put 4 like IV, it have to be IIII

Are you crazy? It costs me hours to correctly parse the input and you say, it's all for nothing?

Actually IIII is an invalid number and you would get error -2 if entering it.


>>>> std:: string i tink would be better

Add

    #include <string>
    using namespace std;

to the top of your cpp file.

Change the first part of Roman function to

int Roman (const string& input)
{
    int amount = 0;  // make a local variable *but* remove the global one
    char RP  = ' ';     // previous
    char RN  = '\0';    // current
    char RNN = '\0';    // next
   
    int expected  = 1000;
    int duplicate = 0;  
    for (int i = 0; i < input.length(); ++i)
    {
        RP  = RN;
        RN  = input[i];
        RNN = input.c_str()[i+1];  // input[i+1] isn't valid for std::string
                                   // if i+1 == input.length()
        ...
        // remainder didn't change


Change main function to

int main()
{
     string input;
     int first, second, result;
     while (true)
     {
        cout << "First Roman  [Q to quit] ==>  ";
        cin >> input;
        if (input == "Q" || input == "q")
            return 0;
 
        first = Roman(input);
        cout << endl << "First = " << first << endl << endl;
        if (first <= 0)
            continue;

        cout << "Second Roman [Q to quit] ==>  ";
        cin >> input;
        if (input == "Q" || input == "q")
            return 0;
 
        second = Roman(input);
        cout << endl << "Second = " << second << endl << endl;

        if (second <= 0)
            continue;
        cout<<"(+) Addition \n(-) Subtraction \n(*) Multiplication \n(/) Division \n(Q) Quit \n\nEnter Choice ==> ";
        cin >> input;      

        if (input == "Q" || input == "q")
            return 0;

        result = Operation(first, second, input[0]);
        cout << endl << "result = " << result << endl << endl;
     }
}

Regards, Alex
0
itsmeandnobodyelseCommented:
>>>> that i dont have to put 4 like IV, it have to be IIII

If you really need a wrong parsing, you have to

- remove all lines and if blocks using RNN variable

- use

    if (duplicate > 3)  

  instead of

    if (duplicate > 2)

  to allow 4 occurences of C, X and I

- use

    if (duplicate > 3)  

  instead of

    if (duplicate)

  to allow 4 occurences of D, L and V

- remove all lines and if blocks using 'expected' variable if you want to allow any order

- remove all lines and if blocks using 'duplicate' variable if you want to allow any number of repetitions

(But save the original if you do any of this. As it is the correct version!!!)

Regards, Alex
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.