#include <stdio.h> #include <ctype.h> // toupper #include <stdlib.h> // strtoul #include <string.h> // strchr // Prevodni tabulky // #define SROMT_INIT "I" "V" "X" "L" "C" "D" "M" #define SVALT_INIT {1, 5, 10, 50, 100, 500, 1000} // static char const sromt[] = SROMT_INIT; // Maximalni velikost bufferu cislic // #define RESULT_SIZE 40 /*============================================================================*\ RIMSKE --> ARABSKE \*============================================================================*/ /* * ZJISTENI POCTU PREDCHOZICH CISLIC S MENSI HODNOTOU */ static int r2a_prevlessnum(int result[], int ridx) { int resval, number; resval = result[ridx]; number = 0; do { int preval; preval = result[--ridx]; if( preval < 0) preval = -preval; if(resval > preval) ++number; } while(ridx > 0); return(number); } /* * VSTUPNI BOD */ static void r2a(char const *valup) { int ridx, result[RESULT_SIZE]; char const *fndp; static int const svalt[] = SVALT_INIT; ridx = 0; do { int sidx; if((fndp = strchr(sromt, toupper(*valup))) == NULL) { fprintf(stderr, "Unknown Digit: %s\n", valup); return; } sidx = fndp - sromt; result[ridx] = svalt[sidx]; if(ridx > 0) switch(r2a_prevlessnum(result, ridx)) { case 1: result[ridx - 1] = -result[ridx - 1]; case 0: break; default: fprintf(stderr, "Unexpected Digit: %s\n", valup); return; } ++ridx; } while(*++valup != '\0'); while(--ridx > 0) result[0] += result[ridx]; printf("%d\n", result[0]); } /*============================================================================*\ ARABSKE --> RIMSKE \*============================================================================*/ /* * VSTUPNI BOD */ static void a2r(unsigned value) { unsigned divisor; int sidx, ridx; char result[RESULT_SIZE]; if(value - 1 >= 3999) { fprintf(stderr, "Bad Range: %u\n", value); return; } divisor = 1000; sidx = sizeof(sromt) / sizeof(*sromt) - 2; ridx = -1; do { unsigned digit; digit = value / divisor; value -= digit * divisor; switch(digit) { case 4: case 9: result[++ridx] = sromt[sidx + 0]; result[++ridx] = sromt[sidx + 1 + (digit == 9)]; break; default: while(digit) { int idx; idx = sidx; if(digit >= 5) { ++idx; digit -= 5 - 1; } result[++ridx] = sromt[idx]; --digit; } } sidx -= 2; } while((divisor /= 10) > 0); result[ridx + 1] = '\0'; puts(result); } /*============================================================================*\ PROGRAM \*============================================================================*/ /* * ZPRACOVANI JEDNOHO RETEZCE */ static void operate(char const *argp) { unsigned value; char *endp; value = strtoul(argp, &endp, 10); if(*endp == '\0') a2r(value); else r2a(argp); } /* * VSTUPNI BOD */ int main(int argc, char *argv[]) { while(--argc > 0) operate(*++argv); return(0); }