# Thread: Using loops for check a roman number input.

1. ## Using loops for check a roman number input.

I have a problem here. How to make a loop to define that the input is roman number.... since my solution is incorrect... Help me... it's make me crazy.... :confused:

Code:
```#include <iostream>
#include <string>

using namespace std;

int main()
{
int value = 0, number, jumlah;
string roman;
char romancheck[]="IiVvXxLlCcDdMm";

/*   while((roman != "I") || (roman != "i")||(roman != "V") || (roman != "v")||
(roman != "X") || (roman != "x")||(roman != "L") || (roman != "l")||
(roman != "C") || (roman != "c")||(roman != "D") || (roman != "d")||
(roman != "M") || (roman != "m"))
{

cout << "Invalid input" << endl;
break;

}

*/

do
{

cout << "Enter a roman number: ";
getline(cin, roman);

if(roman != nonroman)
{
cout << "Invalid output" << endl;
}

if((roman == "IX") || (roman == "ix"))
{
value = 9;
}
else if((roman == "IIX") || (roman == "iix"))
{
value = 8;
}
else if((roman == "IV") || (roman == "iv"))
{
value = 4;
}
else if((roman == "IIV") || (roman == "iiv"))
{
value = 3;
}
else if((roman == "XL") || (roman == "xl"))
{
value = 40;
}

else
{
for (int i=0; i<=roman.length(); i++)
{

char kiraan = roman[i];
kiraan = toupper(kiraan);

switch (kiraan)
{
case 'M' : value+= 1000;
break;
case 'D' : value+= 500;
break;
case 'C':  value+= 100;
break;
case 'L' : value+= 50;
break;
case 'X' : value+= 10;
break;
case 'V' : value+= 5;
break;
case 'I' : value+= 1;
break;

}

}
}
}while(roman == romancheck);

cout << "Roman number " << roman << " in decimal form is " << value << endl;

system ("pause");
return 0;

}```

2. Here is some code I wrote a while back for a course. It gives the correct result for actual Roman Number input, but it doesn't do so good with incorrect values. All you'd have to do is add a few more checks and balances, though. This should get you started on the logic of Roman Numerals:
Code:
```#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <cctype>

class romanType {
public:
romanType();
romanType(std::string);
romanType(int);
romanType(const romanType&);
~romanType() {}

std::string getRoman() { return romanNum; }
int         getDecimal() { return deciNum; }
void        setRoman(std::string rNum) {
romanNum = rNum;
convToDeci();
}
void        setDeci(int dNum) {
deciNum = dNum;
convToRoman();
}
private:
void        convToDeci();
void        convToRoman();
std::string romanNum;
unsigned int deciNum;
};

romanType::romanType() {
deciNum = 0;
romanNum = "";
}

romanType::romanType(std::string rNum) : romanNum(rNum) {
convToDeci();
}

romanType::romanType(int dNum) : deciNum(dNum) {
convToRoman();
}

romanType::romanType(const romanType& copy) {
romanNum = copy.romanNum;
deciNum = copy.deciNum;
}

void romanType::convToDeci() {
bool isRoman = true;

deciNum = 0;
for(int i = romanNum.size() - 1; i >= 0; i--) {
switch(romanNum[i]) {
case 'I':
case 'i':
if (deciNum < 5 || (deciNum >= 5 && romanNum[i+1] == 'I'))
deciNum += 1;
else
deciNum -= 1;
break;
case 'V':
case 'v':
if (deciNum < 10 || (deciNum >= 10 && romanNum[i+1] == 'V'))
deciNum += 5;
else
deciNum -= 5;
break;
case 'X':
case 'x':
if (deciNum < 50 || (deciNum >= 50 && romanNum[i+1] == 'X'))
deciNum += 10;
else
deciNum -= 10;
break;
case 'L':
case 'l':
if (deciNum < 100 || (deciNum >= 100 && romanNum[i+1] == 'L'))
deciNum += 50;
else
deciNum -= 50;
break;
case 'C':
case 'c':
if (deciNum < 500 || (deciNum >= 500 && romanNum[i+1] == 'C'))
deciNum += 100;
else
deciNum -= 100;
break;
case 'D':
case 'd':
if (deciNum < 1000)
deciNum += 500;
else
deciNum -= 500;
break;
case 'M':
case 'm':
deciNum += 1000;
break;
default:
std::cout << "There is no such character \'" << romanNum[i]
<< "\' in the Roman numeric system." << std::endl;
isRoman = false;
break;
}
}
if(romanNum != romanType(deciNum).getRoman() && isRoman) {
std::cout << "I believe " << romanNum << " should be written as ";
convToRoman();
std::cout << romanNum << "." << std::endl;
}
}

void romanType::convToRoman() {
int tempDeci = deciNum;
std::string tempRoman;
romanNum = "";

while(tempDeci > 0) {
if(tempDeci >= 1000) {
tempDeci -= 1000;
romanNum += 'M';
}
else if(tempDeci >= 900) {
tempDeci -= 900;
romanNum += "CM";
}
else if(tempDeci >= 500) {
tempDeci -= 500;
romanNum += 'D';
}
else if(tempDeci >= 400) {
tempDeci -= 400;
romanNum += "CD";
}
else if(tempDeci >= 100) {
tempDeci -= 100;
romanNum += 'C';
}
else if(tempDeci >= 90) {
tempDeci -= 90;
romanNum += "XC";
}
else if(tempDeci >= 50) {
tempDeci -= 50;
romanNum += 'L';
}
else if(tempDeci >= 40) {
tempDeci -= 40;
romanNum += "XL";
}
else if(tempDeci >= 10) {
tempDeci -= 10;
romanNum += 'X';
}
else if(tempDeci >= 9) {
tempDeci -= 9;
romanNum += "IX";
}
else if(tempDeci >= 5) {
tempDeci -= 5;
romanNum += 'V';
}
else if(tempDeci >= 4) {
tempDeci -= 4;
romanNum += "IV";
}
else {
tempDeci -= 1;
romanNum += 'I';
}
}
}

int main() {
romanType r1;
std::string val = "";
int dVal = 0;
bool isRoman;

std::cout << "Roman/Decimal Converter\nI = 1\nV = 5\nX = 10\n"
<< "L = 50\nC = 100\nD = 500\nM = 1000\nQ to Quit\n" << std::endl;
do {
std::cout << "Enter a value to be converted: ";
std::getline(std::cin,val,'\n');

isRoman = true;
for(int i = 0; i < val.size(); i++) {
if (!isalpha(val[i])) {
isRoman = false;
break;
}
else val[i] = toupper(val[i]);
}

if(isRoman && toupper(val[0]) != 'Q') {
r1.setRoman(val);
std::cout << r1.getRoman() << " in decimal is " << r1.getDecimal() << "."
<< std::endl;
}
else if(!isRoman) {
std::istringstream conv;
conv.str(val);
conv >> dVal;
if(dVal > 3999)
std::cout << "Warning: The highest value you can get with the\n"
<< "standard english alphabet is 3999.\nI believe ";
r1.setDeci(dVal);
std::cout << r1.getDecimal() << " in Roman numerals is " << r1.getRoman()
<< "." << std::endl;
}
else
std::cout << "Press any key to exit.";
std::cin.get();
} while(toupper(val[0]) != 'Q');
return 0;
}```
EDIT: More modern vesion for you.

3. string roman;
char romancheck[]="IiVvXxLlCcDdMm";
Why are you using both string types and char arrays? Why not make everything a string type?

Code:
```#include <iostream>
#include <string>
using namespace std;

int main()
{

string roman = "IiVvXxLlCcDdMm";
string input = "CDMaXVL";

if( input.find_first_not_of(roman) == string::npos )
{
cout<<"The input contains all roman numerals.\n\n";
}
else
{
cout<<"The input contains some characters\n"
<<"that are not roman numerals.\n\n";

}

return 0;
}```

4. I`m a beginner... just start the c++ last month... so i`m little confuse about string and arrays...

5. My question is.... how to scan the string containing roman character... if the input is not one of the roman... it will come out "invalid input"... if all correct then the input will be processed... it has a loop so the user can make the input again...

6. Look at my code a few times, then try to write a do-while loop that incorporates that code. One trick you can use is to set a variable like this before the do-while loop:
Code:
`bool getInputAgain = false;`
Inside the loop, get the input from the user. Then use the if statement in my code to set the variable getInputAgain to true or false. Then in your while conditional only continue the loop if getInputAgain == true.

7. My program works.... thanks all because helping me to find the solution.... now can someone explain me the code in english...

Code:
```	   do
{

cout << "Enter a roman number: ";
getline(cin, roman);

if( roman.find_first_not_of(romancheck) == string::npos )
{
getInputAgain = false;
}
else
{
getInputAgain = true;
cout << "Invalid output" << endl;

}
}while(getInputAgain == true );```
i will appreciate that if someone explain it to me....

8. Originally Posted by eryell
now can someone explain me the code in english...
Do... output "Enter a roman number: " then get a string of data from cin and store it into roman. If, when you search all the letters of roman, you never find a letter that isn't in romancheck, then set getInputAgain to false, otherwise set getInputAgain to true, output "Invalid output", go to the next line and clear the buffer. If getInputAgain is true, then do the whole thing again.

It's generally not a good idea to call code "your program" if you don't know what it means.

9. "Your program" means you wrote it in some way, which doesn't seem to be the case

Basically, the code posted above will ask the user for input and TRY to convert it to a roman number. If it fails, then ask again, and again and again until the user enters some input the function can use.

10. Now i understand, because before this i just do it by try and error.... Thanks guys....