다음은  대화형 모드(interactive mode)에서 진법 변환(radix conversion)하는 C 소스 코드이다.
(Ch를 이용하면 컴파일 하지 않고 소스를 그대로 실행시킬 수 있다.)
메뉴는 주메뉴 Command: (S)et radix, (A)bout, (Q)uit or E(x)it
와 부메뉴 SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
로 구성되어 있으며, 진법 변환을 하는 핵심 함수 convertAtoI()와 convertItoA()의 소스가 자체 제작되어 포함되어 있다. 이를 이용하는 부분은 153~154째 줄에 있는

         val = convertAtoI(s, srcRdx);
         convertItoA((char *) ret, val, destRdx);

이다. 지원되는 진법은 2진법에서 36진법 까지이다.



  1. /*
  2.  *  Filename: convertRadix.c
  3.  *            Convert radix in a interactive mode.
  4.  *
  5.  *  Compile: cl convertRadix.c
  6.  *  Execute: convertRadix
  7.  *
  8.  *      Date:  2008/03/25
  9.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  10.  */
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <math.h>
  14. #define MAX_BUF 300
  15. enum { FALSE, TRUE };
  16. struct _TOKEN {
  17.     char a[81];
  18.     char b[81];
  19. };
  20. void println(char s[]) {
  21.     printf("%s\n", s);
  22. }
  23. void print(char s[]) {
  24.     printf("%s", s);
  25. }
  26. void printUsage() {
  27.     println("Usage: convertRadix");
  28.     println("Convert radix in a interactive mode, where the maximum radix is 36.");
  29. }
  30. void printAbout() {
  31.     println("    About: Convert radix in a interactive mode.");
  32. }
  33. void printMainMenu() {
  34.     println("  Command: (S)etup radix, (A)bout, (Q)uit or E(x)it");
  35. }
  36. void printMainPrompt() {
  37.     print("  Prompt> ");
  38. }
  39. void printSubMenu(int srcRadix, int destRadix) {
  40.     char sbuf[MAX_BUF];
  41.     sprintf(sbuf, "    Convert Radix_%d to Radix_%d", srcRadix, destRadix);
  42.     println(sbuf);
  43.     println("    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit");
  44. }
  45. void printSubPrompt() {
  46.     print("    Input Value>> ");
  47. }
  48. char BASE36[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  49. void convertItoA(char *pstr, long num, int radix) {
  50.     char tmp[2];
  51.     char ret[MAX_BUF];
  52.     char arr[MAX_BUF];
  53.     long q, r;
  54.     int i, n;
  55.     int isNegative = FALSE;
  56.     if (num < 0L) {
  57.         isNegative = TRUE;
  58.         num = -num;
  59.     }
  60.     arr[0] = '\0';
  61.     q = num;
  62.     r = 0L;
  63.     while (q >= (long) radix) {
  64.         r = q % (long) radix;
  65.         q = q / (long) radix;
  66.         tmp[0] = BASE36[r];
  67.         tmp[1] = '\0';
  68.         strcat(arr, tmp);
  69.     }
  70.     tmp[0] = BASE36[q];
  71.     tmp[1] = '\0';
  72.     strcat(arr, tmp);
  73.     if (isNegative) {
  74.         strcat(arr, "-");
  75.     }
  76.     n = strlen(arr);
  77.     for (i = 0; i < n; i++) {
  78.         ret[i] = arr[n - i - 1];
  79.     }
  80.     ret[n] = '\0';
  81.     strcpy(pstr, (char *) ret);
  82. }
  83. long convertAtoI(const char *pstr, int radix) {
  84.     long ret = 0L;
  85.     char arr[MAX_BUF];
  86.     long q, r;
  87.     int isNegative = FALSE;
  88.     int len = strlen(pstr);
  89.     char c;
  90.     int i;
  91.     long val;
  92.     c = pstr[0];
  93.     if (c == '-') {
  94.         isNegative = TRUE;
  95.     }
  96.     else if (c >= '0' && c <= '9') {
  97.         ret = (long) (c - '0');
  98.     }
  99.     else if (c >= 'A' && c <= 'Z') {
  100.         ret = (long) (c - 'A') + 10L;
  101.     }
  102.     else if (c >= 'a' && c <= 'z') {
  103.         ret = (long) (c - 'a') + 10L;
  104.     }
  105.     if (ret >= (long) radix) {
  106.         println("        Invalid character!");
  107.         return ret;
  108.     }
  109.     for (i = 1; i < len; i++) {
  110.         c = pstr[i];
  111.         ret *= radix;
  112.         if (c >= '0' && c <= '9') {
  113.             val = (long) (c - '0');
  114.         }
  115.         else if (c >= 'A' && c <= 'Z') {
  116.             val = (long) (c - 'A') + 10L;
  117.         }
  118.         else if (c >= 'a' && c <= 'z') {
  119.             val = (long) (c - 'a') + 10L;
  120.         }
  121.         if (val >= (long) radix) {
  122.             println("        Invalid character!");
  123.             return ret;
  124.         }
  125.         ret += val;
  126.     }
  127.     return ret;
  128. }
  129. void convertRadix(char *pstr, char s[],  int srcRdx, int destRdx) {
  130.     long val;
  131.     char ret[MAX_BUF];
  132.     val = convertAtoI(s, srcRdx);
  133.     convertItoA((char *) ret, val, destRdx);
  134.     strcpy(pstr, ret);
  135. }
  136. void readLine(char *pdata) {
  137.     scanf("%s", pdata);
  138. }
  139. void readTwo(struct _TOKEN *ptoken) {
  140.     scanf("%s", ptoken->a);
  141.     scanf("%s", ptoken->b);
  142. }
  143. void tokenize(struct _TOKEN *ptoken, const char *line, char c) {
  144.     int len = strlen(line);
  145.     int i;
  146.     int from, to;
  147.     i = 0;
  148.     while (line[i] != c) {
  149.         i++;
  150.     }
  151.     from = i;
  152.     while (line[i] == c) {
  153.         i++;
  154.     }
  155.     to = i;
  156.     strncpy(ptoken->a, line, to - from);
  157.     ptoken->a[to - from] = '\0';
  158.     while (line[i] != c) {
  159.         i++;
  160.     }
  161.     from = i;
  162.     while (line[i] == c) {
  163.         i++;
  164.     }
  165.     to = i;
  166.     strncpy(ptoken->b, line, to - from);
  167.     ptoken->b[to - from] = '\0';
  168. }
  169. void doConvert(int srcRadix, int destRadix) {
  170.     char sbuf[MAX_BUF];
  171.     char line[MAX_BUF];
  172.     char cmd[MAX_BUF];
  173.     char srcStr[MAX_BUF], destStr[MAX_BUF];
  174.     long tmp;
  175.     println("");
  176.     printSubMenu(srcRadix, destRadix);
  177.     do {
  178.         printSubPrompt();
  179.         readLine((char *)cmd);
  180.         while (strlen(cmd) <= 0) {
  181.             readLine((char *)cmd);
  182.         }
  183.         if (strcmp("main()", cmd) == 0) {
  184.             return;
  185.         }
  186.         else if (strcmp("exit()", cmd) == 0 || strcmp("quit()", cmd) == 0) {
  187.             exit(0);
  188.         }
  189.         tmp = convertAtoI(cmd, srcRadix);
  190.         strcpy(srcStr, cmd);
  191.         convertRadix(destStr, srcStr, srcRadix, destRadix);
  192.         sprintf(sbuf, "        ( %s )_%d   --->   ( %s )_%d", srcStr, srcRadix, destStr, destRadix);
  193.         println(sbuf);
  194.         println("");
  195.     } while (TRUE);
  196. }
  197. void doStart() {
  198.     char line[MAX_BUF];
  199.     char cmd[MAX_BUF];
  200.     int srcRadix = 10, destRadix = 10;
  201.     char srcStr[MAX_BUF], destStr[MAX_BUF];
  202.     struct _TOKEN st;
  203.     int onlyOnce = TRUE;
  204.     do {
  205.         println("");
  206.         if (onlyOnce) {
  207.             println("  The supported maximum radix is 36.");
  208.             onlyOnce = FALSE;
  209.         }
  210.         printMainMenu();
  211.         printMainPrompt();
  212.         readLine((char *)cmd);
  213.         while (strlen(cmd) <= 0) {
  214.             readLine((char *)cmd);
  215.         }
  216.         if (strstr("qQxX", cmd) != NULL && strlen(cmd) == 1) {
  217.             exit(0);
  218.         }
  219.         else if (strstr("aA", cmd) != NULL && strlen(cmd) == 1) {
  220.             printAbout();
  221.         }
  222.         else if (strstr("sS", cmd) != NULL && strlen(cmd) == 1) {
  223.             print("  Input the source and target radices (say, 16 2): ");
  224.             readTwo((struct _TOKEN *) &st);
  225.             srcRadix = convertAtoI(st.a, 10);
  226.             destRadix = convertAtoI(st.b, 10);
  227.             doConvert(srcRadix, destRadix);
  228.         }
  229.     } while (TRUE);
  230. }
  231. void main(int argc, char *argv[]) {
  232.     if (argc > 1 && strcmp("-h", argv[1]) == 0) {
  233.         printUsage();
  234.         exit(1);
  235.     }
  236.     doStart();
  237. }




컴파일> cl convertRadix.c

실행> convertRadix

  The supported maximum radix is 36.
  Command: (S)etup radix, (A)bout, (Q)uit or E(x)it
  Prompt> s
  Input the source and target radices (say, 16 2): 8 16

    Convert Radix_8 to Radix_16
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> 1234
        ( 1234 )_8   --->   ( 29C )_16

    Input Value>> main()

  Command: (S)etup radix, (A)bout, (Q)uit or E(x)it
  Prompt> s
  Input the source and target radices (say, 16 2): 16 8

    Convert Radix_16 to Radix_8
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> 29c
        ( 29c )_16   --->   ( 1234 )_8

    Input Value>> exit()



Posted by Scripter
,