I've been learning to code for quite some time and my impression from the programming book I have is: "Keep it as simple as possible, but no simpler." I had an assignment to write a program that converts roman numerals to int
s and vice versa, and I've been wondering how bad is the code that I worked on. Is it as terrible as I think it is? Is it because I'm a beginner? The code I wrote works fine, but I would very much appreciate it if you guys could show me a better and shorter way of reaching the same goal with simpler code (something that is definitely possible).
#include "Header.h"
class Roman {
public:
string roman = "";
int number;
int as_int() { return number; }
string int_to_roman(int number);
void think(const char& a, const char& b, const char& c, int& divided, const int & dividee); //meant to ensure the roman permissible
void roman_to_int(Roman a);
};
void Roman::think(const char& a, const char& b, const char& c, int& divided, const int & dividee) {
string name = "";
int number = divided;
number /= dividee;
if (number < 1) return;
if (number == 1)
name += a;
if (number == 2)
name = name+a+a;
if (number == 3)
name = name+a+a+a;
if (number == 4)
name = name + a+b;
if (number == 5)
name = b;
if (number == 6)
name = name + b+a;
if(number==7)
name = name + b+a+a;
if(number==8)
name = name + b+a+a+a;
if(number==9)
name = name + a+c;
if(number== 10)
name += c;
int z = divided;
divided = (z - (number * dividee));
roman += name;
}
string Roman::int_to_roman(int number) {
if (number > 4999) error("Doesn't support numbers higher than 5000");
think('C', 'D', 'M', number, 100);
think('X', 'L', 'C', number, 10);
think('I', 'V', 'X', number, 1);
return roman;
}
void Roman::roman_to_int(Roman a){
}
ostream& operator << (ostream& os, Roman a) {
return os << a.roman;
}
int test(char ch, int how_much) {
if (cin.get() == ch) return how_much;
cin.unget();
return 0;
}
void dis(char const& a, char const& b, int& sum, int times, string& numeral) {
sum += (1*times);
int number = sum;
sum += test(a, (3*times));
if (number != sum) {
numeral += a;
return;
}
sum += test(b, (8*times));
if (number != sum) numeral += b;
}
int get_number(Roman &a) {
int sum = 0;
string numeral = "";
while (cin.get()!='\n') {
cin.unget();
char ch = cin.get();
numeral += ch;
switch (ch) {
case'I':
dis('V', 'X', sum, 1, numeral);
break;
case'V': sum += 5;
break;
case'X': dis('L', 'C', sum, 10, numeral);
break;
case'L': sum += 50;
break;
case'C': dis('D', 'M', sum, 100, numeral);
break;
case'D': sum += 500;
break;
case'M': sum += 1000;
break;
}
}
if (numeral != a.int_to_roman(sum)) error("Impermissible roman, try again.\n");
return sum;
}
int main() {
while (true) {
try {
while (true) {
Roman a;
cout << "Please write a roman numeral and press enter.\n";
a.number = get_number(a);
cout << a.number << ", " << a << endl;
}
system("pause");
return 0;
}
catch (exception& e) {
cerr << "error: \n" << e.what() << '\n ';
//return 1; // 1 - indicates failure
}
}
}
As a neophyte programmer it would really mean a lot to me to know if I'm doing things well enough or whether I can do any better regarding the code's brevity and efficiency.
Edit: To the requests of some people, this is what Header.h contains:
#include <algorithm>
#include <cmath>
#include <vector>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
using namespace std;
void error(const string& a) {
throw runtime_error(a);
}
Header.h
contains, and things such asstring roman = "";
will not compile withoutusing namespace std;
. \$\endgroup\$