发一段UNICODE UTF-8互转代码简洁版



http://bbs.chinaunix.net/thread-1370274-1-1.html


有了这个你可以任意打印unicode表的所有字符, 最近因为要搞一个单字表, 弄了一天才弄出来, 最近代码效率太低了...
主要是对UTF-8编码不熟悉, 今天重新学习了一下, 发上来跟大家共享一下学习成果, 哈哈

gcc -o unicode unicode.c -D_DEBUG_UNICODE
unicode.h

  1. #ifndef _UNICODE_H
  2. #define _UNICODE_H
  3. /* convert unicode to UTF-8 */
  4. unsigned char *UnicodetoUTF8(int unicode, unsigned char *p);
  5. #define UNICODE_TO_UTF8(unicode, e)                                             \
  6. do                                                                              \
  7. {                                                                               \
  8.     if(e && unicode != 0)                                                       \
  9.     {                                                                           \
  10.         if(unicode < 0x80) *e++ = unicode;                                      \
  11.         else if(unicode < 0x800)                                                \
  12.         {                                                                       \
  13.             /*<11011111> < 000 0000 0000>*/                                     \
  14.             *e++ = ((unicode >> 6) & 0x1f)|0xc0;                                \
  15.             *e++ = (unicode & 0x3f)|0x80;                                       \
  16.         }                                                                       \
  17.         else if(unicode < 0x10000)                                              \
  18.         {                                                                       \
  19.             /*<11101111> <0000 0000 0000 0000>*/                                \
  20.             *e++ = ((unicode >> 12) & 0x0f)|0xe0;                               \
  21.             *e++ = ((unicode >> 6) & 0x3f)|0x80;                                \
  22.             *e++ = (unicode & 0x3f)|0x80;                                       \
  23.         }                                                                       \
  24.         else if(unicode < 0x200000)                                             \
  25.         {                                                                       \
  26.             /*<11110111> <0 0000 0000 0000 0000 0000>*/                         \
  27.             *e++ = ((unicode >> 18) & 0x07)|0xf0;                               \
  28.             *e++ = ((unicode >> 12) & 0x3f)|0x80;                               \
  29.             *e++ = ((unicode >> 6) & 0x3f)|0x80;                                \
  30.             *e++ = (unicode & 0x3f)|0x80;                                       \
  31.         }                                                                       \
  32.         else if(unicode < 0x4000000)                                            \
  33.         {                                                                       \
  34.             /*<11111011> <00 0000 0000 0000 0000 0000 0000>*/                   \
  35.             *e++ = ((unicode >> 24) & 0x03)|0xf8 ;                              \
  36.             *e++ = ((unicode >> 18) & 0x3f)|0x80;                               \
  37.             *e++ = ((unicode >> 12) & 0x3f)|0x80;                               \
  38.             *e++ = ((unicode >> 6) & 0x3f)|0x80;                                \
  39.             *e++ = (unicode & 0x3f)|0x80;                                       \
  40.         }                                                                       \
  41.         else                                                                    \
  42.         {                                                                       \
  43.             /*<11111101> <0000 0000 0000 0000 0000 0000 0000 0000>*/            \
  44.             *e++ = ((unicode >> 30) & 0x01)|0xfc;                               \
  45.             *e++ = ((unicode >> 24) & 0x3f)|0x80;                               \
  46.             *e++ = ((unicode >> 18) & 0x3f)|0x80;                               \
  47.             *e++ = ((unicode >> 12) & 0x3f)|0x80;                               \
  48.             *e++ = ((unicode >> 6) & 0x3f)|0x80;                                \
  49.             *e++ = (unicode & 0x3f)|0x80;                                       \
  50.         }                                                                       \
  51.     }                                                                           \
  52. }while(0)

  53. /* convert UTF-8 to unicode */
  54. int UTF8toUnicode(unsigned char *ch, int *unicode);
  55. #define UTF8_TO_UNICODE(p, e, n)                                                \
  56. do                                                                              \
  57. {                                                                               \
  58.     if(p)                                                                       \
  59.     {                                                                           \
  60.         if(*p >= 0xfc)                                                          \
  61.         {                                                                       \
  62.             /*6:<11111100>*/                                                    \
  63.             e = (p[0] & 0x01) << 30;                                            \
  64.             e |= (p[1] & 0x3f) << 24;                                           \
  65.             e |= (p[2] & 0x3f) << 18;                                           \
  66.             e |= (p[3] & 0x3f) << 12;                                           \
  67.             e |= (p[4] & 0x3f) << 6;                                            \
  68.             e |= (p[5] & 0x3f);                                                 \
  69.             n = 6;                                                              \
  70.         }                                                                       \
  71.         else if(*p >= 0xf8)                                                     \
  72.         {                                                                       \
  73.             /*5:<11111000>*/                                                    \
  74.             e = (p[0] & 0x03) << 24;                                            \
  75.             e |= (p[1] & 0x3f) << 18;                                           \
  76.             e |= (p[2] & 0x3f) << 12;                                           \
  77.             e |= (p[3] & 0x3f) << 6;                                            \
  78.             e |= (p[4] & 0x3f);                                                 \
  79.             n = 5;                                                              \
  80.         }                                                                       \
  81.         else if(*p >= 0xf0)                                                     \
  82.         {                                                                       \
  83.             /*4:<11110000>*/                                                    \
  84.             e = (p[0] & 0x07) << 18;                                            \
  85.             e |= (p[1] & 0x3f) << 12;                                           \
  86.             e |= (p[2] & 0x3f) << 6;                                            \
  87.             e |= (p[3] & 0x3f);                                                 \
  88.             n = 4;                                                              \
  89.         }                                                                       \
  90.         else if(*p >= 0xe0)                                                     \
  91.         {                                                                       \
  92.             /*3:<11100000>*/                                                    \
  93.             e = (p[0] & 0x0f) << 12;                                            \
  94.             e |= (p[1] & 0x3f) << 6;                                            \
  95.             e |= (p[2] & 0x3f);                                                 \
  96.             n = 3;                                                              \
  97.         }                                                                       \
  98.         else if(*p >= 0xc0)                                                     \
  99.         {                                                                       \
  100.             /*2:<11000000>*/                                                    \
  101.             e = (p[0] & 0x1f) << 6;                                             \
  102.             e |= (p[1] & 0x3f);                                                 \
  103.             n = 2;                                                              \
  104.         }                                                                       \
  105.         else                                                                    \
  106.         {                                                                       \
  107.             e = p[0];                                                           \
  108.             n = 1;                                                              \
  109.         }                                                                       \
  110.     }                                                                           \
  111. }while(0)
  112. #endif
复制代码


unicode.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include "unicode.h"
  6. #define CHINA_SET_MAX 8
  7. int outbin(FILE *fp, char ch)
  8. {
  9.     int i = 7;
  10.     while(i >= 0)
  11.     {
  12.         fprintf(fp, "%d", ((ch >> i) & 1));
  13.         i--;
  14.     }
  15. }

  16. /* convert unicode to UTF-8 */
  17. unsigned char *UnicodetoUTF8(int unicode, unsigned char *p)
  18. {
  19.     unsigned char *e = NULL;

  20.     if((e = p))
  21.     {
  22.         if(unicode < 0x80) *e++ = unicode;
  23.         else if(unicode < 0x800)
  24.         {
  25.             /*<11011111> < 000 0000 0000>*/
  26.             *e++ = ((unicode >> 6) & 0x1f)|0xc0;
  27.             *e++ = (unicode & 0x3f)|0x80;
  28.         }
  29.         else if(unicode < 0x10000)
  30.         {
  31.             /*<11101111> <0000 0000 0000 0000>*/
  32.             *e++ = ((unicode >> 12) & 0x0f)|0xe0;
  33.             *e++ = ((unicode >> 6) & 0x3f)|0x80;
  34.             *e++ = (unicode & 0x3f)|0x80;
  35.         }
  36.         else if(unicode < 0x200000)
  37.         {
  38.             /*<11110111> <0 0000 0000 0000 0000 0000>*/
  39.             *e++ = ((unicode >> 18) & 0x07)|0xf0;
  40.             *e++ = ((unicode >> 12) & 0x3f)|0x80;
  41.             *e++ = ((unicode >> 6) & 0x3f)|0x80;
  42.             *e++ = (unicode & 0x3f)|0x80;
  43.         }
  44.         else if(unicode < 0x4000000)
  45.         {
  46.             /*<11111011> <00 0000 0000 0000 0000 0000 0000>*/
  47.             *e++ = ((unicode >> 24) & 0x03)|0xf8 ;
  48.             *e++ = ((unicode >> 18) & 0x3f)|0x80;
  49.             *e++ = ((unicode >> 12) & 0x3f)|0x80;
  50.             *e++ = ((unicode >> 6) & 0x3f)|0x80;
  51.             *e++ = (unicode & 0x3f)|0x80;
  52.         }
  53.         else
  54.         {
  55.             /*<11111101> <0000 0000 0000 0000 0000 0000 0000 0000>*/
  56.             *e++ = ((unicode >> 30) & 0x01)|0xfc;
  57.             *e++ = ((unicode >> 24) & 0x3f)|0x80;
  58.             *e++ = ((unicode >> 18) & 0x3f)|0x80;
  59.             *e++ = ((unicode >> 12) & 0x3f)|0x80;
  60.             *e++ = ((unicode >> 6) & 0x3f)|0x80;
  61.             *e++ = (unicode & 0x3f)|0x80;
  62.         }
  63.     }
  64.     return e;
  65. }

  66. /* convert UTF-8 to unicode */
  67. int UTF8toUnicode(unsigned char *ch, int *unicode)
  68. {
  69.     unsigned char *p = NULL;
  70.     int e = 0, n = 0;

  71.     if((p = ch) && unicode)
  72.     {
  73.         if(*p >= 0xfc)
  74.         {
  75.             /*6:<11111100>*/
  76.             e = (p[0] & 0x01) << 30;
  77.             e |= (p[1] & 0x3f) << 24;
  78.             e |= (p[2] & 0x3f) << 18;
  79.             e |= (p[3] & 0x3f) << 12;
  80.             e |= (p[4] & 0x3f) << 6;
  81.             e |= (p[5] & 0x3f);
  82.             n = 6;
  83.         }
  84.         else if(*p >= 0xf8)
  85.         {
  86.             /*5:<11111000>*/
  87.             e = (p[0] & 0x03) << 24;
  88.             e |= (p[1] & 0x3f) << 18;
  89.             e |= (p[2] & 0x3f) << 12;
  90.             e |= (p[3] & 0x3f) << 6;
  91.             e |= (p[4] & 0x3f);
  92.             n = 5;
  93.         }
  94.         else if(*p >= 0xf0)
  95.         {
  96.             /*4:<11110000>*/
  97.             e = (p[0] & 0x07) << 18;
  98.             e |= (p[1] & 0x3f) << 12;
  99.             e |= (p[2] & 0x3f) << 6;
  100.             e |= (p[3] & 0x3f);
  101.             n = 4;
  102.         }
  103.         else if(*p >= 0xe0)
  104.         {
  105.             /*3:<11100000>*/
  106.             e = (p[0] & 0x0f) << 12;
  107.             e |= (p[1] & 0x3f) << 6;
  108.             e |= (p[2] & 0x3f);
  109.             n = 3;
  110.         }
  111.         else if(*p >= 0xc0)
  112.         {
  113.             /*2:<11000000>*/
  114.             e = (p[0] & 0x1f) << 6;
  115.             e |= (p[1] & 0x3f);
  116.             n = 2;
  117.         }
  118.         else
  119.         {
  120.             e = p[0];
  121.             n = 1;
  122.         }
  123.         *unicode = e;
  124.     }
  125.     return n;
  126. }
  127. #ifdef _DEBUG_UNICODE
  128. int main()
  129. {
  130.     unsigned char ch[CHINA_SET_MAX], *p = NULL, *e = NULL, *s = NULL;
  131.     int i = 0, n = 0, unicode = 0;

  132. #ifdef _OUT_UNICODE_
  133.        for(i = 1; i < 65536; i++)
  134.        {
  135.            p = (unsigned char *)&i;
  136.            outbin(stdout, p[0]);
  137.            fprintf(stdout, " ");
  138.            outbin(stdout, p[1]);
  139.            fprintf(stdout, " ");
  140.            outbin(stdout, p[2]);
  141.            fprintf(stdout, " ");
  142.            outbin(stdout, p[3]);
  143.            e = ch;
  144.            s = unicodetoUTF8(i, e);
  145.            *s = '\0';
  146.            while(*e != 0)
  147.            {
  148.                fprintf(stdout, "[");
  149.                outbin(stdout, *e++);
  150.                fprintf(stdout, "]");
  151.            }
  152.         }
  153. #endif
  154.     //macro functions
  155.     sprintf((char *)ch, "%s", "你");
  156.     e = ch;
  157.     unicode = 0;
  158.     UTF8_TO_UNICODE(e, unicode, n);
  159.     fprintf(stdout, "convert UTF8_TO_UNICODE(%s, %08x, %d)\n", ch, unicode, n);
  160.     memset((char *)ch, 0, CHINA_SET_MAX);
  161.     e = ch;
  162.     UNICODE_TO_UTF8(unicode, e);
  163.     e = '\0';
  164.     fprintf(stdout, "convert UNICODE_TO_UTF8(%08x, %s)\n", unicode, ch);
  165.     //C functions
  166.     unicode = 0;
  167.     if((n = UTF8toUnicode(ch, &unicode)) > 0)
  168.     {
  169.         fprintf(stdout, "convert %d = UTF8toUnicode(%s, %08x)\n", n, ch, unicode);
  170.         memset((char *)ch, 0, CHINA_SET_MAX);
  171.         if((e = UnicodetoUTF8(unicode, ch)) > ch)
  172.         {
  173.             e = '\0';
  174.             fprintf(stdout, "convert UnicodetoUTF8(%08x, %s)\n", unicode, ch);
  175.         }
  176.     }
  177.     return 0;
  178. }
  179. #endif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值