Roman Numeral Project using classes

Pages: 12
Here is the problem:
"Write a program that converts a number entered in Roman numerals to a positive integer. Your program should consist of a class, say, romanType. An object of type romanType should do the following:
a. Store the number as a positive integer.
b. Convert and store the number as a positive integer.
c. Print the number as a Roman numeral or positive integer as requested by the user.
The integer values of the Roman numerals are:
M 1000
D 500
C 100
L 50
X 10
V 5
I 1
d. Test your program using the following Roman numerals: MCXIV, CCCLIX, MDCLXVI."

I'm doing the best I can to understand the concept of the class. Here is what I have (which is not much thus far, and nowhere near correct I'm sure).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<iostream>
#include<iomanip>
using namespace std;

class romanType
{
public:
	void getRoman();
	void printValue();
};

void getRoman()
{
	char numeral;

	cout << "Please enter a Roman Numeral.\n";
	cin >> numeral;
}

void printValue()
{
	
}


Some feedback is needed please.
I would start with a constructor for "romanType". Something that takes an unsigned (positive) integer would be a good start. From there converting it into an std::string seems appropriate, that way you can just look up each numerical value with the element access operator ("[]")* against a compile-time-populated "std::map" of std::strings to uint's and concatenate the results into a return value from there.

EDIT *: Remember to account for the arabic numerals position.
Last edited on
ok... after a few days... this is what I have. I have a better understanding of the classes but still having issues. can someone give me some feedback. questions are in the code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<iostream>
#include<iomanip>
#include<string>
using namespace std;

class romanType
{
private:
	string numeral;

public:
	void setRoman(string roman)
	{
		numeral = roman;
	}

	string getRoman()
	{
		return roman; // why am I getting a syntax error on "roman" if it is declared above?
	}
	void printValue(); // I understand this has no value at this point.
};
Do you really need a class for this? There is no state or anything like that, it's just a conversion.

I'd expect to see two functions, std::string toRoman(int) and int fromRoman(const std::string&);, ... or something like that.
THANK YOU! I said that as well, but that is what the assignment says to do. I've done a similar assignment a while back, and did not even know classes existed. But THIS assignment wants me to use a class.
I've been able to get a little further, but still am having trouble. It's been a while since I coded anything. Here is what I have.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include<iostream>
#include<iomanip>
#include<string>
using namespace std;

class romanType
{
private:
	string numeral;
	int intValue, total;
public:
	void setRoman(string roman)
	{
		numeral = roman;
	}

	string getRomanNumeral()
	{
		return numeral;
	}

	int calculateIntValue()
	{
		char numeral[7] = { 'M', 'D', 'C', 'L', 'X', 'V', 'I'};// convert numeral to char Array
		cout << "Enter a roman numeral.\n";
		cout << "Roman Numerals are as follows:\n";
		cout << "  M = 1000\n" << "  D = 500\n" << "  C = 100\n" << "  L = 50\n" << "  X = 10\n" << "  V = 5\n" << "  I = 1\n";
		cin >> numeral;//example input: MDXII... output should be 1512 for this example.
		
		for (int x = 1; x <= 7; x++)
		{
			cout << x << endl;
		}// iterate through array and assign numeric value to each element of array (keep running total)
		// return running total
		return total;
	}
};

int main()
{
	romanType romanNumeral;
	//romanNumeral.setRoman();//Want user input to get the value of setRoman... possible?
	int value = romanNumeral.calculateIntValue();
	return 0;
}
I can't work out what you've done. I ran it and it didn't seem clear up how that contributes to a solution.

For example, what's the significance of: for (int x = 1; x <= 7; x++)?

Anyway, the process is similar to converting decimal to binary, except:
1. you map what you devide by to Roman Numberal
2. you have to mess around with the placement of characters to represent values (.e.g. IV vs VI)

If would help if you help the decimal value withe the Roman value. e.g.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct Numeral
{
    Numeral(char c = 'I', int v = 1) : roman(c), value(v) {}
    char roman;
    int value;
};

std::vector<Numeral> numerals = {
    { 'M', 1000 },
    { 'D', 500 },
    { 'C', 100 },
    { 'L', 50 },
    { 'X', 10 },
    { 'V', 5 },
    { 'I', 1 }
};

Is a vector a type of array that declares the values of the char? I'm not familiar with vectors. The only purpose of that particular for loop was to ensure I had the syntax correct and the placement correct. It really served no other purpose. The for loop is supposed to basically add up the numerals based on what the user types in and keeps a running total to output the integer value. I am just not sure how to do this. I'm thinking of getline would be appropriate.
@dub1987

1
2
3
4
5
6
7
int calculateIntValue()
	{
		char numeral[7] = { 'M', 'D', 'C', 'L', 'X', 'V', 'I'};// convert numeral to char Array
		cout << "Enter a roman numeral.\n";
		cout << "Roman Numerals are as follows:\n";
		cout << "  M = 1000\n" << "  D = 500\n" << "  C = 100\n" << "  L = 50\n" << "  X = 10\n" << "  V = 5\n" << "  I = 1\n";
		cin >> numeral;//example input: MDXII... output should be 1512 for this example. 


You declare an array named numeral, and fill it with the desired data, BUT then you ask for a roman numeral, and overwrite what you just declared. Shouldn't you use a different name for the input?
Well, the IDEA was to declare it to be the values it is supposed to be, then ask the user to input what roman numeral they want to see in integer form. If you have a better idea to make it less confusing please feel free to share. I'm not entirely sure. The whole "class" portion has thrown me through a loop.
@dub1987

Here is a program that takes the roman numeral input, then converts it to decimals. It does not use a class though, but you can see here on how to convert, and find a way to incorporate it into the class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Roman Numeral Convert.cpp : main project file.

#include<iostream>
#include<iomanip>

using std::cout;
using std::cin;
using std::endl;
using std::string;

void printValue(char numeral[15])
{
 int RomanValues[7] = {1000,500,100,50,10,5,1};
 char Roman[7] = {'M','D','C','L','X','V','I'};
 int number = 0, ck[15] = {0},len = 0;
 bool ok = false;
 for(int x=0;x<15;x++)
	if (numeral[x] !='\0')
	 len++; //Find how long the numeral input was
	else
	 x=15;

 for(int x=0;x<len;x++)
 {
	ok = false;
	for(int y=0;y<7;y++)
	{
	 if(numeral[x] == Roman[y])
		ok = true; // Making sure the inputs were all Roman numerals
	}
	if( !ok )
	{
	 cout << "Sorry, the '" << numeral[x] << "' is NOT a Roman Numeral." << endl << "Try again.." << endl << endl;
	 return;
	}
 }
 for(int x=0;x<len;x++)
 {
	for(int y=0;y<7;y++)
	{
	 if(numeral[x] == Roman[y])
	 {
		ck[x] = RomanValues[y];// Fill array ck with decimal value of inputted Roman #
	 }
	}
 }
 for(int x=0;x<len;x++)
 {
	if((ck[x+1] > ck[x]))
	{
	 number+=(ck[x+1] - ck[x]); // If number is lower than next number, subtract
   // So IV is 4 and VI is 6
	 x++;
	}
	else
	 number+=ck[x]; // else add
 }
 cout << number<< endl << endl;
}

void Menu()
{
 cout << "\tRoman Numeral Values" << endl << endl;
 cout << "\t\tM = 1000" << endl;
 cout << "\t\tD =  500" << endl;
 cout << "\t\tC =  100" << endl;
 cout << "\t\tL =   50" << endl;
 cout << "\t\tX =   10" << endl;
 cout << "\t\tV =    5" << endl;
 cout << "\t\tI =    1" << endl;

}

void getRoman()
{
 char numeral[15];

 do
 {
	Menu();
	cout << endl << "Please enter a Roman Numeral.\n(Enter 'Q', to end program)" << endl;
	cin >> numeral;
	for(int x=0;x<15;x++)
	 numeral[x] = toupper(numeral[x]);
	if(numeral[0] == 'Q')
	 cout << "Program terminating!" << endl;
	else
	 printValue( numeral);
 }while (numeral[0] != 'Q');
}

int main()
{
 getRoman();
 return 0;
}
I will give this a try and use it as a reference. (I'm not 1 to copy someone's code). I'll post what I have some time tomorrow.
this is what I came up with... I apologize for the late reply and I have one issue, that I can tell. I'm not sure whats wrong with my loop. It loops 15 times to get the correct number, but prints 15 times as well. If I change it to 1, it does not get the correct number and prints 1 time. I'm figuring my cout statement is within the loop but when I go look for it, I don't see it within the loop. Here is my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include<iostream>
#include<iomanip>
using namespace std;

class romanType
{
public:
	void displayChoices(char numeral[15])
	{
		cout << "Enter a roman numeral.\n";
		cout << "Roman Numerals are as follows:\n";
		cout << "  M = 1000\n" << "  D = 500\n" << "  C = 100\n" << "  L = 50\n" << "  X = 10\n" << "  V = 5\n" << "  I = 1\n";

		while (numeral[0] != 'Q')
		{
			cout << "\nTo quit, press Q.\n";
			cin >> numeral;

			for (int x = 0; x < 15; x++)
			{
				numeral[x] = toupper(numeral[x]);
				if (numeral[x] == 'Q')
				{
					cout << "Thank you for using my Roman Numeral Conversion Program.\n";
				}
				else
					romansArray(numeral);
			}
		}
	}
	void romansArray(char numeral[15])
	{
		int RomanValues[7] = { 1000, 500, 100, 50, 10, 5, 1 };
		char Roman[7] = { 'M', 'D', 'C', 'L', 'X', 'V', 'I' };
		int number = 0, check[15] = { 0 }, numLen = 0, x = 0;
		bool ok = false;

		for (int x = 0; x < 15; x++)// x incriments to fill the array 'numeral' up to 15 blocks
		{
			if (numeral[x] != '\0')
				numLen++; // Without this incriment, the value of the roman numeral will be set to 0.
			else
				x = 15;
		}

		for (int x = 0; x < numLen; x++) //Incriments to see how long the user input was.
		{
			ok = false;
		}

		for (int y = 0; y < 7; y++) //Incriments to store the roman numeral as an integer.
		{
			if (numeral[x] == Roman[y])
			{
				ok = true;
			}
			if (ok = false)
			{
				cout << "Not a valid input. Please try again.\n\n";
			}
		}

		for (int x = 0; x < numLen; x++)
		{

			for (int y = 0; y < 7; y++)
			{
				if (numeral[x] == Roman[y])
				{
					check[x] = RomanValues[y];
				}
			}
		}

		for (int x = 0; x < numLen; x++)
		{
			if ((check[x + 1] > check[x]))
			{
				number += (check[x + 1] - check[x]);
				x++;
			}
			else
				number += check[x];
		}
		cout << number << endl << endl;
	}
	void setRoman(char roman)
	{
		roman = numeral;
	}
	char getRoman()
	{
		return numeral;
	}

private:
	char numeral;
};

int main()
{
	char choice[15] = "";
	char romans[15] = "";
	char number = 0;

	romanType romanObject;
	romanObject.displayChoices(choice);
	romanObject.romansArray(romans);
	romanObject.setRoman(number);
	cout << romanObject.getRoman();

	return 0;
}
@dub1987

Your displayChoices() function is at fault. When you loop the 15 times, it's only needed to make sure the inputted values were all capital letters, or that the first input was a 'Q' to show you were ending the program. Here it is corrected, along with explanations. You still have mistakes while checking for correct inputted values. Input wrong and it still shows a number for what values were inputted as a Roman numeral. So 'CDIXB' shows incorrect input 14 times, then shows the value of 409.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void displayChoices(char numeral[15])
	{
		cout << "Enter a roman numeral.\n";
		cout << "Roman Numerals are as follows:\n";
		cout << "  M = 1000\n" << "  D = 500\n" << "  C = 100\n" << "  L = 50\n" << "  X = 10\n" << "  V = 5\n" << "  I = 1\n";

			cout << "\nTo quit, press Q.\n";
			cin >> numeral;

			for (int x = 0; x < 15; x++)
					numeral[x] = toupper(numeral[x]);
				if (numeral[0] == 'Q') // Just need to check first input to see if they want to quit
				{
					cout << "Thank you for using my Roman Numeral Conversion Program.\n";
				}
				else
					romansArray(numeral);
			}
The suggested code will print the correct number followed by a 0 and an unknown character before the "press any key to continue." Not sure what that is all about.
@dub1987

You have some unneeded code at the end of your main function, and some wrong coding in the romansArray() function. You have a single equals to assign false to the ok variable, where it should be double equals to just check for equality. Here is your corrected code. It's still not perfect, but is a lot better.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include<iostream>
#include<iomanip>
using namespace std;

class romanType
{
public:
	void displayChoices(char numeral[15])
	{
		cout << "Enter a roman numeral.\n";
		cout << "Roman Numerals are as follows:\n";
		cout << "  M = 1000\n" << "  D = 500\n" << "  C = 100\n" << "  L = 50\n" << "  X = 10\n" << "  V = 5\n" << "  I = 1\n";

			cout << "\nTo quit, press Q.\n";
			cin >> numeral;

			for (int x = 0; x < 15; x++)
					numeral[x] = toupper(numeral[x]);
				if (numeral[0] == 'Q') // Just need to check first input to see if they want to quit
				{
					cout << "Thank you for using my Roman Numeral Conversion Program.\n";
				}
				else
					romansArray(numeral);
			}
	void romansArray(char numeral[15])
	{
		int RomanValues[7] = { 1000, 500, 100, 50, 10, 5, 1 };
		char Roman[7] = { 'M', 'D', 'C', 'L', 'X', 'V', 'I' };
		int number = 0, check[15] = { 0 }, numLen = 0, x = 0;
		bool ok = false;

		for (x = 0; x < 15; x++)// x incriments to fill the array 'numeral' up to 15 blocks
		{
			if (numeral[x] != '\0')
				numLen++; // Without this incriment, the value of the roman numeral will be set to 0.
			else
				x = 15;
		}

		for ( x = 0; x < numLen; x++) //Incriments to see how long the user input was.
		{
			ok = false;
		

		for (int y = 0; y < 7; y++) //Incriments to store the roman numeral as an integer.
		{
			if (numeral[x] == Roman[y])
			{
				ok = true;
			}
		}
if (ok == false)
			{
				cout << "Not a valid input. Please try again.\n\n";
return;
			}
}
		for (int x = 0; x < numLen; x++)
		{

			for (int y = 0; y < 7; y++)
			{
				if (numeral[x] == Roman[y])
				{
					check[x] = RomanValues[y];
				}
			}
		}

		for (int x = 0; x < numLen; x++)
		{
			if ((check[x + 1] > check[x]))
			{
				number += (check[x + 1] - check[x]);
				x++;
			}
			else
				number += check[x];
		}
		cout << number << endl << endl;
	}
	void setRoman(char roman)
	{
		roman = numeral;
	}
	char getRoman()
	{
		return numeral;
	}

private:
	char numeral;
};

int main()
{
	char choice[15] = "";
	char romans[15] = "";
	char number = 0;

	romanType romanObject;
	romanObject.displayChoices(choice);
	//romanObject.romansArray(romans);
	//romanObject.setRoman(number);
	//cout << romanObject.getRoman();
	return 0;
}
so I do NOT need those last 3 statements in my main?
Correct. Nor the char number = 0. It's never used, plus it should been followed with a pair of single quotes, as should been choice[] and romans[].
char romans[15] = ''; would not be needed in that case either. It was meant to fill the void of the object romansArray... correct?
That's also correct. And you can leave off the = "", after choice[15], leaving char choice[15];. I guess though, it wouldn't hurt if you leave it alone, either.
Pages: 12