Hello, I'm a complete newbie in programming and this is the first programming class I'm taking.
We are supposed to make a program that convert a double into a Uppercase Roman Number and then convert the Uppercase format into a lowercase.And then display the first 20 roman numbers using arrays where the initial number is incremented by 1.
The output is supposed to be something like this:
initial Upcase Lowercase
125 CXXV cxxv
126 CXXVI cxxvi
127 CXXVII cxxvii
(and so on...)
The problem is that my program displays a pretty messed up output. Data are not displayed at the position I set for them.
This is the output I get :
cxxv 125 CXXV CXXVCXXVI
You are trying to do far too many things at once. Forum users will baulk at trying to sort out too much confusion. Break it down into smaller tasks and check that each one works individually before trying to throw the lot together.
General comments:
- I don't think the Romans did fractions, so you will be converting an int, not a double;
- you do not need arrays to do any of this: just write out your answer as a table (not the same as an array).
Task 1 - convert an int (not a double) into a roman numeral. Correct to have a string-returning function, but your conversion is both wrong and very over-complicated. Remember that roman numerals use "subtraction notation" in places - e.g. 4 is IV, not IIII. Get this working first, and check it separately, before doing anything else.
Task 2 - convert a string to lowercase. Given what you intend to do this probably has the prototype
string lowercase( string stringtest );
As it stands, your function argument is passed by value, not reference, so it won't change anything in the calling program. Check this routine separately before going on.
Task 3 - write out a table. Just loop on i and cout, on each line,
i, roman(i), lowercase(roman(i))
(which you could make slightly more efficient by evaluating roman(i) in the loop, rather than twice).
In short, ask for help with small specific parts. Also don't include unnecessary or commented-out code (like your Mystring routine).
@lastchance
Thank you very much for your feedback.
You are making very good points but the problem is that it's an assignment and I have to follow a set of rules.
Task 1 - My teacher asked for the long-form notation, he is therefore expecting 4 to be IIII. But you are right about the int conversion, I fixed it.
Task 2 - I actually checked the function separately and it was working just fine (separately).
Task 3 - I am required to do it with 2 parallel arrays, otherwise I get no credit.
My problem is why is the lowercase appearing first in the row while I set it to appear last (The order is: Integer Upcase Lowercase)?
And why am I getting that extra Uppercase Roman number at the end of the row since I am supposed to have 3 rows only? And how can I fix that?
Any help would be very appreciated.
Well, I've tried to make your code work with minimal interference - you can check it on cpp-shell (the little gear-wheel to the top right of code samples once you have logged in). Also note any warnings that throws up - they aren't errors, but they indicate where your code could be improved.
A lot of your spurious output comes from the cout lines that you left in roman() - presumably whilst developing/debugging. You need to "walk through" your code with pen and paper, following the calculations and output it undertakes.
You can see from my comments that I think there is quite a lot that you might do to make the code more efficient.
I'm sorry, but I think arrays are completely unnecessary here ... but I've left StringArray[][] in for now. It really serves no purpose.
// #include "stdafx.h" // put back for Visual Studio if used
#include <iostream>
#include <string>
#include<cctype>
#include<iomanip>
#include<cmath>
usingnamespace std;
// Function Prototypes
string roman( int num ); // <==== int, not double
// <==== removed Mystring
string lowercase(string stringtest); // <==== return a string
int main()
{
constint IMIN = 1, IMAX = 20; // <==== define range
int number = 0; // <==== int, not double
string StringArray[IMAX+1][2]; // <==== don't use magic numbers
// <==== DoubleArray not needed
// <==== next section removed as irrelevant
for (int iRow = IMIN; iRow <= IMAX; iRow++) // <==== don't use "magic numbers"
{
StringArray[iRow][0] = roman( iRow ); // <==== just use the loop index!!
StringArray[iRow][1] = lowercase( roman( iRow ) );
// <==== lines removed as irrelevant
cout << setw(4 ) << iRow << " "
<< setw(10) << StringArray[iRow][0] << " "
<< setw(10) << StringArray[iRow][1] << endl;
}
// system("pause"); // put back for Visual Studio if used
}
string roman( int num ) // <==== int, not double
{
int m, d, c, l, x, v, i, n;
string string1 = "";
m = num / 1000;
d = ((num % 1000) / 500); // <==== this lot is really painful! consider rewriting it
c = ((num % 500) / 100); // <====
l = ((num % 100) / 50); // <====
x = ((num % 50) / 10); // <====
v = ((num % 10) / 5); // <====
i = (num % 5); // <====
n = m + d + c + l + x + v + i;
while (n > 0) // <==== there are much simpler ways of doing this
{
for (m; m>0; m--) string1.append("M");
for (d; d>0; d--) string1.append("D");
for (c; c>0; c--) string1.append("C");
for (l; l>0; l--) string1.append("L");
for (x; x>0; x--) string1.append("X");
for (v; v>0; v--) string1.append("V");
for (i; i>0; i--) string1.append("I");
n--;
}
// <==== removed cout statements (presumably left over from development)
return string1;
}
// <==== removed MyString
string lowercase( string stringtest ) // <===== note that stringtest is being passed by VALUE
{
for (unsignedint i = 0; i < stringtest.length(); ++i)
{
stringtest[i] = tolower(stringtest[i]);
}
return stringtest; // <===== this is the return value of the function, NOT a modified argument
}
FWIW, and since your teacher won't let you use "real" roman-numeral notation, here is my conversion routine:
#include <iostream>
#include <string>
usingnamespace std;
//======================================================================
string dec( int i, char sym, char sym5, char sym10 ) // return roman 'digit' as a string
{
string s = "";
if ( i == 9 ) s = ( s + sym ) + sym10;
elseif ( i == 4 ) s = ( s + sym ) + sym5;
elseif ( i >= 5 ) s += sym5 + string( i - 5, sym );
elseif ( i >= 0 ) s += string( i, sym );
return s;
}
//======================================================================
string roman( int n ) // convert integer num to roman numeral (as a string)
{
int m = n / 1000; n %= 1000;
int c = n / 100 ; n %= 100 ;
int x = n / 10 ; n %= 10 ;
int i = n;
return string( m, 'M' )
+ dec( c, 'C', 'D', 'M' )
+ dec( x, 'X', 'L', 'C' )
+ dec( i, 'I', 'V', 'X' );
}
//======================================================================
int main()
{
int n = 1;
while ( n > 0 )
{
cout << "Input n (or 0 to end): ";
cin >> n;
if ( n > 0 ) cout << "Roman numeral: " << roman( n ) << "\n\n";
}
}
//======================================================================
Input n (or 0 to end): 34
Roman numeral: XXXIV
Input n (or 0 to end): 199
Roman numeral: CXCIX
Input n (or 0 to end): 2017
Roman numeral: MMXVII
Input n (or 0 to end): 0
Oh no! This is going to be pretty hard coding! Especially since, according to the wikipedia link, their whole numbers use decimal and their fractions duodecimal.
And all my information on Romans cutting things in half comes from Asterix and Obelix!