Solved

# help please, simple C program, seeking help to write a  function to convert any given year into its roman equivalent

Posted on 2004-08-14
934 Views
Hi experts,

I am trying to write a general purpose function to convert any given year into its roman equivalent.
Decimal                   Roman            decimal            roman
1            i            100            c
5            v            500            d
10            x            1000            m
50            l

Example 1: 1988 = mdcccclxxxviii>>m=1000, d+c+c+c+c=900, l+x+x+x=80, v+i+i+i=8 total 1988.
Example 2:  1525 = mdxxv.

My question is how will I return this value? (mdcccclxxxviii or what ever I get for the equivalent years) ?
Suppose the name of the function is roman()
So if I write a program like this.

char roman(int)
void main()
/*pass the value to the function*/
roman(n);
}
char roman(int n)
{
/*code for converting the year to roman*/
return();
here is my problem how will I return the value since it will be  something like a string, ?
}
Or are there any other method to do this? I just started learning C and all I know is loops, functions , swirch and the if-else (decision controls). I have to do solve this using the these tools.

Please donâ€™t write the code for this, just guide me the proper way. Thanks a lot in advance
deep
0
Question by:deepthiji
• 10
• 9
• 4
• +1

LVL 7

Expert Comment

You could do this two ways -- return a pointer to a string such as:

char *roman(int nvalue)
{
-- allocate a string buffer in the function, put the converted string and return the pointer to it.
Note:  the caller would have to free() the returned string when done to avoid a memory leak.
}

or fill a string buffer with the converted string:

int roman( char *romanbuff, int nbufsize)
{
-- caller passes a pointer to a buffer and the buffer's length. Function converts the number
using the buffer.
Note: the buffer needs to be long enough to hold the converted string.
}
0

LVL 7

Expert Comment

Oops. The second example is flawed. It should be:

int roman(int nvalue, char *romanbuff, int nbufsize)
{
...
}
0

LVL 3

Author Comment

jimwasson
I think you might have misunderstood the problem,
The important thing here is I am new in C and all i know is" Loops, If-else,Switch and Function". And offcourse there is someway to solve the above problem using these tools. I have to write this program using a function.
Thanks ,,,, sorry my language is not that great.
0

LVL 7

Expert Comment

Maybe I don't understand... Do you mean the "return" part like so?

char *roman(int nvalue)
{
-- allocate a string buffer in the function, put the converted string and return the pointer to it.
Note:  the caller would have to free() the returned string when done to avoid a memory leak.

char * buff = malloc(256);
... put converted string into buff
return buff;
}

or

int roman(int nvalue, char *romanbuff, int nbufsize)
{
int ncount;
-- caller passes a pointer to a buffer and the buffer's length. Function converts the number
using the buffer. put length of string in ncount;
Note: the buffer needs to be long enough to hold the converted string.

return ncount;
}
0

LVL 3

Author Comment

hi Jimwasson,

I think what you are explainning is correct, but i dont understand <( because i dont know strings, malloc, or anything, I am a student and learnning C by myself, I just reached Functions. What i know at present is Loops, If-else,Switch and functions. Nothing else.
The above mentioned question can surely be written using these (If-else, Switch,Loops and function)

Below mentioned is the proogram that i tried to write using(If-else, Switch,Loops and function), This might not be the correct approach. When i Approached like this i had trouble returnning the value.
If there is no other way to return a string kind of value(using loops,switch,if-else ) then my approach will be wrong. My Ultimate Aim is to Write a program using function to convert any year to its roman equivalent.

>>>>So if I write a program like this.

>>>char roman(int)
>>void main()
>>/*pass the value to the function*/
>>roman(n);
>>}
>>char roman(int n)
>>{
>>/*code for converting the year to roman*/
>>return();
>>here is my problem how will I return the value since it will be  something like a string, ?
>>}
0

LVL 9

Expert Comment

>>here is my problem how will I return the value since it will be  something like a string, ?

Exactly.Strings in C are character arrays.so you'd return a pointer to char in the function to indicate the address of the array where the converted roman value(as a char. array) is stored.
If you dont want to get into malloc() and free() right now,use the second example mentioned by jimwasson.

In your main(),define a char array:
char str[100];
int n=2004; //your year as an integer.

pass the char array to the function:
roman(str,n);

In the function defn:
void roman(char str[],int n)
{
//store the converted value in str just as you access a char array.
}
0

LVL 9

Expert Comment

0

LVL 3

Author Comment

Sorry for the delay, was sleeping.>)
Ok, i know it can be written using strings, But i have to write a FUNCTION  to convert year into roman equivalent using any of these(Loops, If-Else,Swtich).We CANNOT use STRINGS,MALLOC,etc, etc......... ONLY Thing i can use is Loops, If-else, Switch .
Please considor that i CANNOT use arrays or anthing.
>>>here is my problem how will I return the value since it will be  something like a string, ?
What I meant here is,
I wrote a code for the above problem and for that i need to return a string, But i cannot use String. So What i wrote is wrong. There is some Other way to write this function Using(Loops, If-else, Switch ).
Now Forget about my previous Questions,<) I will put my question like this.......
Is there any way i can write a function using Loops, If-else, Switch statement to convert anyyear to its Roman equivalent.
Table below shows the roman equivalents of decimal numbers.
Decimal                  Roman          decimal              roman
1                               i                   100                   c
5                               v                   500                  d
10                             x                   1000                m
50                             l
Example 1: 1988 = mdcccclxxxviii>>m=1000, d+c+c+c+c=900, l+x+x+x=80, v+i+i+i=8 total 1988.
Example 2:  1525 = mdxxv.>>m=1000, d=500, x+x=20, v=5.Total 1525.
If some one entered 1988, the program should give the output as mdcccclxxxviii
similarly for 1525 = mdxxv.
Hope Now my question is Clear, Please considor, English is not my first language.Sorry for the trouble.
thanks
deep
0

LVL 7

Expert Comment

But you have defined a function -- int roman(int nvalue, char *romanbuff, int nbufsize) is a function. You would call it in your main():

/* Define the function roman() before it is to be called */
int roman(int nvalue, char *romanbuff, int nbufsize);
{
int ncount;
-- caller passes a pointer to a buffer and the buffer's length. Function converts the number
using the buffer. put length of string in ncount;
Note: the buffer needs to be long enough to hold the converted string.

return ncount;
}

void main()
{
int nlength = 0;
int nvalue = 10552;
int nbuffsize = 256;
char *buffer[256];
/* call the function with the value to convert */
nlength = roman(nvalue, buffer, nbuffsize);
}

As for "...i CANNOT use arrays or anthing....". There isn't a STRING type in C. Strings in C are character arrays. So if you cannot use arrays at all the only other option I can think of is to return a structure -- which would be pretty strange.

0

LVL 3

Author Comment

Thanks Jimwasson,
I dont think your other option will also work, because i cannot use structure also >)
I am pretty much sure that there is some easy way to write this function using Loops, If-else, Switch .
I am trying to find the answer key of my book, Let me see if i can find out.
Thanks once again for the help.
0

LVL 9

Expert Comment

I think what you're looking for is a recursive solution.Are you familiar with recursive functions.

Here's an idea on how to do the conversion using a recursive function:
>>
Sometimes, recursion can produce dramatically smaller programs.To convert an integer in the range 0 to 3999 to its Roman numeral equivalent,two premises are required:

We know the Roman numerals for the numbers 0 to 9 (null, I, II, ..., IX), and can perform this conversion with a simple pattern match.

We can use the REPLACE function to "multiply" a number in Roman form by 10 by replacing I by X, V by L, X by C, etc.

The function uses these two rules to produce a recursive solution for some integer N. The algorithm looks like this:

The rightmost digit is removed from the argument and converted by premise 1. Removing the digit effectively divides the argument by 10, simplifying the problem.

The reduced argument is then converted by calling ROMAN recursively and "multiplying" the result by 10 according to premise 2.

The previously converted unit's digit is appended to the result.
<<
0

LVL 9

Expert Comment

See here:
http://guideme.itgo.com/atozofc/

This has an array implementation of the conversion.To do it without arrays,you can replace the array indexing part with a bunch of if/else's.
0

LVL 3

Assisted Solution

CmdrRickHunter earned 100 total points
Does it actually have to RETURN the roman numeral?  Could it instead print out the roman numeral right there?

ex:
int myDecimalNumber = 5;
printf ("%i in roman numerals is", myDecimalNumber);
PrintRomanNumeral(myDecimalNumber);

then, in the PrintRomanNumeral function, you print the roman numeral out.

this being opposed to the way I believe you are trying to do it:
char numeral[100];
int myDecimalNumber = 5;
/* some function which puts the roman numeral into the "numeral" string here */
printf ("%i in roman numerals is %s", myDecimalNumber, numeral);

0

LVL 3

Author Comment

hi CmdrRickHunter,

>>Does it actually have to RETURN the roman numeral?  Could it instead print out the roman numeral right there?

I just want to print the roman numeral, I have to write this function and have to call the function from main() and if i enter any year it has to print the equivalent roman numeral, thats it. Could you please explain how can i print it?
0

LVL 9

Expert Comment

Deep,

Without using arrays,you'll have to use recursion.
Which way do you want it?
The array method is quite simple to understand and code.

Are you familiar with recursion???
0

LVL 3

Author Comment

>>Are you familiar with recursion???
Yea i am familiar with recursion.
I just want to print the roman numeral, I dont want to return(). Sorry for the trouble.
I thought if i want to print it i have to return it.
Is there any way i can write that with loops, Anyway i am familiar with recursion. Dosent matter you can write using recursion.
thanks
0

LVL 9

Accepted Solution

ankuratvb earned 400 total points
Check the link i gave you.In Chapter 10,they have an implementation using arrays.
You can easily convert it to not using arrays.

Try it and see.If there's a problem,post back.

I'd give you the converted code but that'd be no good to you and i'd be violating EE rules as well.
0

LVL 3

Author Comment

>>I'd give you the converted code but that'd be no good to you

Exactly, i am trying  and will get back,
0

LVL 3

Author Comment

Sorry for the delay,
Ankuratvb, thanks a lot for the help. Could you pleaase check my code and give some suggestion to improve the code. This code is working fine in the range 0-5000.

#include<stdio.h>
#include<conio.h>
void main()
{
int i,j,k,l,m,a,n,p,q,r,s;
clrscr();
printf ("Enter the year");
scanf ("%d",&n);

i=0;
while(n!=0)
{
for(j=1000;j>=1;j/=10)
{
a=n/j;
n=n%j;
if(a<5&&j==1000)
{
for(k=a;k>0;k--)
printf ("%c",'m');
}
else if(a>=5&&j==100)
{
printf ("%c",'d');
for(l=a-5;l>0;l--)
printf ("%c",'c');
}
else if(a<5&&j==100)
{
for(m=a;m>0;m--)
printf ("%c",'c');
}
else if(a>=5&&j==10)
{
printf ("%c",'l');
for(p=a-5;p>0;p--)
printf ("%c",'x');
}
else if(a<5&&j==10)
{
for(q=a;q>0;q--)
printf ("%c",'x');
}
else if(a>=5&&j==1)
{
printf ("%c",'v');
for(r=a-5;r>0;r--)
printf ("%c",'i');
}
else if(a<5&&j==1)
{
for(s=a;s>0;s--)
printf ("%c",'i');
}
}
i++;
}

getch();
}
0

LVL 3

Expert Comment

well, one thing:  the assignment may have requested that 4 be represented as 'iiii', but its supposed to be 'iv'.  if the assignment expects 'iv', this code will not work.

it doesn't make the code better, but it will make it more readable:
instead of printf("\$c", 'i'), how about just printf("i")   =)

annother thing, you can reuse variables.  There's nothing wrong with

int i;
for (i = 0; i < 5; i++) {
// do something
}

for (i = 0; i < 6; i++) {
// do something else
}

it looks cleaner.  When someone like me reads the program, if I see a bunch of variables, I assume that they all have different uses, so I need to remember what they did from section to section.  If I only see one variable, and it gets reused, I know that its old value is unimportant - one less thing to keep up in your head.

also, you have a bunch of stuff like this section:

else if(a>=5&&j==100)
{
printf ("%c",'d');
for(l=a-5;l>0;l--)
printf ("%c",'c');
}
else if(a<5&&j==100)
{
for(m=a;m>0;m--)
printf ("%c",'c');
}

Do you see the two copies of the "for" loop?  They do awefully similar things.  Compare the reability of the above code to this:
if (j == 100) {
if (a >= 5) {
printf("%c", 'm');
a -= 5; //  a = a - 5
}
for (k = a; k > 0; k--)
printf("%c", 'c');
}

much more elegant, and as an added bonus, you got rid of the many &&s, which get confusing.
Annother thing, which wont matter until you get much further along in programming.  loops which count "up" are much more common than loops that count "down".  Because of this, other programmers can read loops that count "up" faster than those that count down.  for(k = a; k > 0; k--) will do something "a" times.  You could also write it as for (k = 0; k < a; k++).  The only difference in execution is that 'k' now counts up.  However, now any versed C coder can read it in a little under half of a second, instead of needing two or three.
Again, that makes little difference in the actual execution, but its little things like these that make it easier to read.  And the easier it is to read, the more the teacher will like it (assuming he/she actually looks at the code).  They like it when they get to read code quickly.

also, j can equal 1000, 100, 10, or 1.  Rather than the compound if/elseif/elseif/elseif/else combination, this is what the "switch" statement is for

switch(j) {
case 1000:
for (k = 0; k < a; k++)
printf ("m");
break;
case 100:
if (a >= 5) {
printf("d");
a -= 5;
}
for(k = 0; k < a; k++)
printf("c");
break;
// etc.  just keep filling it out.

one last thing.  You have 'i' being incremented with every loop, but never used.  I'm guessing thats there as a remenant of debug code (or a previous attempt), but there's no since in confusing someone, and there's no point in wasting 'i', which is by far the most common variable name in existance =p

I would consider this "readable" code.  If you wanted to further simplify it, you could return to your usage of the printf("%c"...), with something like this:
char fives, ones;
switch (j) {
case 1000:
fives = "q"; // heh, I don't remember what the 5000's symbol is =p
ones = 'm';
break;
case 100:
fives = 'd';
ones = 'c';
break;
// etc, fill 'em out
}
if (a >=5) {
printf ("%c", fives);
a-= 5;
}
for (i = 0; i < a; i++)   // since we're no longer using i in the big loop, lets use it here
printf ("%c", ones);

by doing this, we minimize the repeated code.  And that means less to read, less to type, etc.  very good thing.
0

LVL 3

Author Comment

CmdrRickHunter,
Thanks a looooot for the comment. Thats an Awesome work. I am really thankful to you.
i just started learnning C and you made my BIGGGG code into very small one. >)
Thanks once again for the comment. Please go to the link below and some comments there
http://www.experts-exchange.com/Programming/Programming_Languages/C/Q_21097401.html
thanks deep
0

LVL 9

Expert Comment

Sorry.I didnt see your comment asking for suggestions on the program.

This is what i had in mind.

void InRoman(int n ) /* converts arabic to roman */
{
int i;
int v;
while (n!=0)
{
if(n>=1) {i=0;v=1;}
if(n>=4) {i=1;v=4;}
if(n>=5) {i=2;v=5;}
if(n>=9) {i=3;v=9;}
if(n>=10) {i=4;v=10;}
if(n>=40) {i=5;v=40;}
if(n>=50) {i=6;v=50;}
if(n>=90) {i=7;v=90;}
if(n>=100) {i=8;v=100;}
if(n>=400) {i=9;v=400;}
if(n>=500) {i=10;v=500;}
if(n>=900) {i=11;v=900;}
if(n>=1000) {i=12;v=1000;}
if(n>=9999) {i=13;v=9999;}

n =n-v;
switch(v)
{
case 1:printf("I");break;
case 4:printf("IV");break;
case 5:printf("V");break;
case 9:printf("IX");break;
case 10:printf("X");break;
case 40:printf("XL");break;
case 50:printf("L");break;
case 90:printf("XC");break;
case 100:printf("C");break;
case 400:printf("CD");break;
case 500:printf("D");break;
case 900:printf("CM");break;
case 1000:printf("M");break;
//case 9999:printf("Value for 9999");break;//couldnt remember the roman value for 9999
}
}
}

These are the values using which you can construct all other roman numerals for the range 1-9999.
0

LVL 9

Expert Comment

Your code doesnt take into consideration the special cases like 4,9,40,90,400,900.
These values have a smaller numeral value before a larger numeral value and in such a case the effective value is subtracting the smaller value from the larger value.

for e.g. IX
X=10
I=1
IX=10-1=9
0

LVL 3

Author Comment

Thanks a lot ankuratvb,
Thats an awesome work too. I did not think about those special cases, Dumb <(
Hope fully i will improve when i learn and write more, Hoping the same support in the future, Now i am struggling to write a program which gives out prime factors>)>). After i done with that i will post that as another question, If you have time please comment on that too, it might take time though
Iwill be really thankful to you guys.
thanks
deep
0

LVL 9

Expert Comment

I am not sure but if 9999 doesnt have a special value comment out this line as well:
//if(n>=9999) {i=13;v=9999;}

Then it'll calculate and give you the value for 9999.
0

## Join & Write a Comment Already a member? Login.

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn hoâ€¦
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to useâ€¦
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

#### 772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

#### Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!