/* roman.c - convert a value to a roman numeral representation */ /* PUBLIC DOMAIN - Jon Mayo - January 31, 2007 */ #include static const struct { const char *str; unsigned val; } romantab[] = { {"M", 1000}, {"CM", 900}, {"D", 500}, {"CD", 400}, {"C", 100}, {"XC", 90}, {"L", 50}, {"XL", 40}, {"X", 10}, {"V", 5}, {"IV", 4}, {"I", 1}, /* we do not walk off the end because of carefully designed code. * changing value>0 to allow the inner for loop to see value as 0 would * walk off the end. */ }; /* return 0 on overflow. string won't be null terminated */ int to_roman(char *buf, size_t max, unsigned value) { size_t len; unsigned rome; const char *s; rome=0; len=0; while(value>0) { while(romantab[rome].val > value) { rome++; } for(s=romantab[rome].str;*s;s++) { if(max<=len) return 0; /* overflow */ buf[len++]=*s; } value-=romantab[rome].val; } if(max<=len) return 0; /* overflow */ buf[len]=0; return len; } /* test routine */ #if STAND_ALONE #include int main() { char buf[40]; memset(buf, '-', sizeof buf); buf[sizeof buf-1]=0; printf("result: %d. '%s'\n", to_roman(buf, sizeof buf, 4999), buf); memset(buf, '-', sizeof buf); buf[sizeof buf-1]=0; printf("result: %d. '%s'\n", to_roman(buf, 4, 4999), buf); memset(buf, '-', sizeof buf); buf[sizeof buf-1]=0; printf("result: %d. '%s'\n", to_roman(buf, sizeof buf, 1999), buf); return 0; } #endif