# Need help with Roman Numerals

• 03-26-2003
kiddprogrammer
Need help with Roman Numerals
Hi, I need help with my program. All i want it to do is accept a number from 1 to 1000 then return a roman numeral.
I know i can use pointers and arrays, but i don't understand them so i was going to do some smple division, but i need help putting it into c.

main()
int number, breakdown;
scanf("%i", %number);

I wanted to do something like this (try to follow)

breakdown= number % 1000
if breakdown = 0
printf("M");
else
breakdown= number % 900
if breakdown => 0
printf ("CM")
--skip down to the fifty section becuase 500 and 100 can't be between 900 and 1000--

breakdown= number % 500
if breakdown => 0
printf("D")

breakdown= breakdown-500
breakdown=breakdown % 100
if breakdown => 1 then
printf("C")

ok Im going to stop now becuase I have a feeling Im getting way off.
does anyone follow..?

I'll be back in a few hours to post what else i got.
• 03-26-2003
Prelude
I find that a table driven method works better in this situation. Here is a simple example:
Code:

```#include <stdio.h> #include <stdlib.h> struct conversion {   int arabic;   char *roman; }; static struct conversion conv[] = {   { 1000, "M", },   { 900,  "CM", },   { 500,  "D", },   { 400,  "CD", },   { 100,  "C", },   { 90,  "XC", },   { 50,  "L", },   { 40,  "XL", },   { 10,  "X", },   { 9,    "IX", },   { 5,    "V", },   { 4,    "IV", },   { 1,    "I", }, }; #define TABSIZ(tab) sizeof tab / sizeof tab[0] static int in_range ( int val, int low, int high ) {   return val >= low && high >= val; } int main ( void ) {   int val;     for ( ; ; ) {     size_t i;         printf ( "Enter an number 1-1000 (0 to quit): " );     if ( scanf ( " %d", &val ) != 1 || !in_range ( val, 0, 1000 ) ) {       fprintf ( stderr, "Invalid input\n" );       exit ( EXIT_FAILURE );     }     else if ( val == 0 )       break;         for ( i = 0; i < TABSIZ ( conv ); i++ ) {       while ( val >= conv[i].arabic ) {         val -= conv[i].arabic;         printf ( "%s", conv[i].roman );       }     }   }     return EXIT_SUCCESS; }```
-Prelude
• 03-26-2003
kiddprogrammer
Thanks Prelude.
I compiled and ran your code and It works and all, but its a little to complicated for me.
I dont understand how the program actually converts
im pretty sure it in here:

for ( i = 0; i < TABSIZ ( conv ); i++ ) {
while ( val >= conv[i].arabic ) {
val -= conv[i].arabic;
printf ( "%s", conv[i].roman );

its just too simple.
Can you explain a few things for me?

1. static int in_range ( int val, int low, int high )
{
return val >= low && high >= val;
}
I thoght this part was defining the range (the number must be between 0 and 1000), but then later you have this

printf ( "Enter an number 1-1000 (0 to quit): " );
if ( scanf ( " %d", &val ) != 1 || !in_range ( val, 0, 1000 ) ) {
fprintf ( stderr, "Invalid input\n" );
exit ( EXIT_FAILURE );
}

2. I know stderr is to display error messages, but ive never seen it used.

3.what do the periods mean (ie --> conv[i].arabic )

4. i think this ---> size_t i; changes the size of the array...does it?

5. I want to edit your code a little bit so i can understand it, but i have to go back to the lab bauces my compiler doesnt work on my lab tob, but would somethign like this work:

#include <stdio.h>
#include <stdlib.h>

struct conversion
{
int arabic;
char *roman;
};

static struct conversion conv[] = {
{ 1000, "M", },
{ 900, "CM", },
{ 500, "D", },
{ 400, "CD", },
{ 100, "C", },
{ 90, "XC", },
{ 50, "L", },
{ 40, "XL", },
{ 10, "X", },
{ 9, "IX", },
{ 5, "V", },
{ 4, "IV", },
{ 1, "I", },
};

#define TABSIZ(tab) sizeof tab / sizeof tab[0]

int main ( void )
{
int val;

for ( ; ; ) {
size_t i;

printf ( "Enter an number 1-1000 (0 to quit): " );
scanf ( " %d", &val )

exit ( EXIT_FAILURE );
}
else if ( val == 0 )
break;

for ( i = 0; i < TABSIZ ( conv ); i++ ) {
while ( val >= conv[i].arabic ) {
val -= conv[i].arabic;
printf ( "%s", conv[i].roman );
}
}
}

return EXIT_SUCCESS;
}
• 03-26-2003
kiddprogrammer
Sorry i clicked post back to it:
#include <stdio.h>
#include <stdlib.h>

struct conversion
{
int arabic;
char *roman;
};

static struct conversion conv[] = {
{ 1000, "M", },
{ 900, "CM", },
{ 500, "D", },
{ 400, "CD", },
{ 100, "C", },
{ 90, "XC", },
{ 50, "L", },
{ 40, "XL", },
{ 10, "X", },
{ 9, "IX", },
{ 5, "V", },
{ 4, "IV", },
{ 1, "I", },
};

#define TABSIZ(tab) sizeof tab / sizeof tab[0]

int main ( void )
{
int val;

for ( ; ; ) {
size_t i;

printf ( "Enter an number 1-1000 (0 to quit): " );
scanf ( " %d", &val )
if (val < 0)
printf("Number has to be between 0 and 1000");
if (val > 1000)
printf("Number has to be between 0 and 1000");
if (val== 0)
break
}

for ( i = 0; i < TABSIZ ( conv ); i++ ) {
while ( val >= conv[i].arabic ) {
val -= conv[i].arabic;
printf ( "%s", conv[i].roman );
}
}
}

return EXIT_SUCCESS;
}
• 03-26-2003
kiddprogrammer
awesome i think i figured it out, tell me if im right..

------------------------------------
printf ( "Enter an number 1-1000 (0 to quit): " );
if ( scanf ( " %d", &val ) != 1 || !in_range ( val, 0, 1000 ) ) {
fprintf ( stderr, "Invalid input\n" );
exit ( EXIT_FAILURE );
------------------------------------

ok this means:
user is promted to enter a number
if the number does not? = 1 OR its not in the range from 0 to 1000
print "invalid input"
and exit

does that make sense?

the only thing i dont understand is, can't you just say if its not in the range to then it askes you to enter the number again?
• 03-26-2003
Prelude
>if the number does not? = 1 OR its not in the range from 0 to 1000
Close, it says "if scanf fails to read one item OR the item read is not in the range of 0 to 1000".

>can't you just say if its not in the range to then it askes you to enter the number again?
That is another option when it comes to input validation. But that particular solution takes up more space, and I didn't want to hide the actual conversion with highly flexible error handling.

>1. static int in_range ( int val, int low, int high )
>I thoght this part was defining the range (the number must be between 0 and 1000)
This is a function that returns true if val is between low and high or equal to either.

>2. I know stderr is to display error messages, but ive never seen it used.
Now you have. :)

>3.what do the periods mean (ie --> conv[i].arabic )
The period is used to access members of a structure, in this case conv[i] is an element in an array of structures and arabic is a member of conv[i].

>4. i think this ---> size_t i; changes the size of the array...does it?
No, i is simply an index for the array. The size is static.

-Prelude
• 04-01-2003
kiddprogrammer
thanks again.
if anyone wants to see the great working finished product, just ask in this post.
later