免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7856 | 回复: 6
打印 上一主题 下一主题

[C] utf8与ucs2互转 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-05-13 17:27 |只看该作者 |倒序浏览
10可用积分
刚开始接触c,现在需要实现utf8和ucs2的互转,在网上也找到好几个,但是都无法编译通过,哪位兄弟有能用的分享下?谢谢!

论坛徽章:
0
2 [报告]
发表于 2009-05-13 18:07 |只看该作者

为啥不用libiconv呢?

UCS2-BE(近似UTF-16)与UTF-8的转换。

  1. static int utf8toucs2(const char **inbuf, size_t *inbytes,
  2.         char **outbuf, size_t *outbytes)
  3. {   
  4.     u_int8_t mark;
  5.     u_int16_t uc = 0;
  6.     char * obuf  = NULL;
  7.     const char *ibuf, *ibuf_end, *obuf_end;
  8.     if ((inbuf&&inbytes&&outbuf&&outbytes)
  9.             && (*inbuf&&*inbytes&&*outbuf&&*outbytes)){
  10.         ibuf = *inbuf;
  11.         ibuf_end = *inbuf+*inbytes;
  12.         obuf = *outbuf;
  13.         obuf_end = *outbuf+*outbytes;
  14.         int follow = 0;
  15.         while(ibuf<ibuf_end && &obuf[1]<obuf_end){
  16.             mark = (u_int8_t)*ibuf++;
  17.             if (mark<0xF0 && mark>0xE0){
  18.                 /* 1110XXXX */
  19.                 uc = mark&0x0F;
  20.                 follow = 2;
  21.             }else if (mark<0xE0 && mark>0xC0){
  22.                 /* 110XXXXX */
  23.                 uc = mark&0x1F;
  24.                 follow = 1;
  25.             }else if (mark<0x80){
  26.                 /* 0XXXXXXX */
  27.                 uc = mark;
  28.                 follow = 0;
  29.             }else{
  30.                 /* convert fail: 0xF0 0xE0 should NOT in UTF-8 seq */
  31.                 printf("convert fail 0xF0 0xE0\n");
  32.                 break;
  33.             }
  34.             if (&ibuf[follow] > ibuf_end){
  35.                 /* unexpect input end */
  36.                 break;
  37.             }
  38.             for (; follow>0; follow--){
  39.                 /* 10XX.XXXX 0x80-0xBF*/
  40.                 if ((*ibuf&0xC0) != 0x80){
  41.                     *outbytes = obuf_end - *outbuf;
  42.                     *inbytes = ibuf_end - *inbuf;
  43.                     printf("convert fail SEQ\n");
  44.                     return 0;
  45.                 }
  46.                 uc = (uc<<6)|(*ibuf++&0x3F);
  47.             }
  48.             *obuf++ = (uc>>8);
  49.             *obuf++ = uc;
  50.             *outbuf = obuf;
  51.             *inbuf = ibuf;
  52.         }
  53.         *outbytes = obuf_end - *outbuf;
  54.         *inbytes = ibuf_end - *inbuf;
  55.     }
  56.     return 0;
  57. }

  58. static int cs2toutf8(const char **inbuf, size_t *inbytes,
  59.         char **outbuf, size_t *outbytes)
  60. {
  61.     u_int16_t uc = 0;
  62.     char *obuf  = NULL;
  63.     const char *ibuf, *ibuf_end, *obuf_end;
  64.     if ((inbuf&&inbytes&&outbuf&&outbytes)
  65.             && (*inbuf&&*inbytes&&*outbuf&&*outbytes)){
  66.         ibuf = *inbuf;
  67.         ibuf_end = *inbuf+*inbytes;
  68.         obuf = *outbuf;
  69.         obuf_end = *outbuf+*outbytes;
  70.         int follow = 0;
  71.         while(&ibuf[1]<ibuf_end && obuf<obuf_end){
  72.             uc = (0xFF&*ibuf++);
  73.             uc = (0xFF&*ibuf++)|(uc<<8);
  74.             if (uc < 0x80){
  75.                 *obuf++ = (uc);
  76.                 follow = 0;
  77.             }else if (uc < 0x800){
  78.                 *obuf++ = (uc>>6)|0xC0;
  79.                 follow = 1;
  80.             }else {
  81.                 /* assert(uc<=0xFFFF); */
  82.                 *obuf++ = (uc>>12)|0xE0;
  83.                 follow = 2;
  84.             }
  85.             if (&obuf[follow] > obuf_end){
  86.                 /*no output buffer */
  87.                 break;
  88.             }
  89.             for (follow--;follow>=0;follow--){
  90.                 int shift = follow*6;
  91.                 u_int8_t ch = uc>>shift;
  92.                 *obuf++ = (ch&0x3F)|0x80;
  93.             }
  94.             *outbuf = obuf;
  95.             *inbuf = ibuf;
  96.         }
  97.         *outbytes = obuf_end - *outbuf;
  98.         *inbytes = ibuf_end - *inbuf;
  99.     }
  100.     return 0;
  101. }

  102. int main(int argc, char *argv[])
  103. {
  104.     char buff[]="中国";
  105.     char obuff[1024];
  106.     char *pin, *pout;
  107.     size_t inlen, outlen;
  108.     pin = buff, pout=obuff;
  109.     inlen = strlen(buff);
  110.     outlen = sizeof(obuff);
  111.     utf8toucs2(&pin, &inlen, &pout, &outlen);
  112.     write(1, obuff, sizeof(obuff)-outlen);
  113.     return 0;
  114. }

复制代码

[ 本帖最后由 pagx 于 2009-5-13 18:08 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2009-05-13 18:45 |只看该作者
#include <iconv.h>
iconv_open
iconv

google

论坛徽章:
0
4 [报告]
发表于 2009-05-14 17:22 |只看该作者
非unix环境,不可以使用iconv.h吧?
最好是纯c的

论坛徽章:
7
酉鸡
日期:2013-10-30 17:17:51水瓶座
日期:2014-01-25 14:47:21天秤座
日期:2014-02-20 09:49:50处女座
日期:2014-11-04 17:44:082015年亚洲杯之中国
日期:2015-03-09 17:21:312015亚冠之北京国安
日期:2015-06-01 16:58:552015亚冠之山东鲁能
日期:2015-06-19 11:30:08
5 [报告]
发表于 2009-05-14 18:46 |只看该作者
网上找找apache的代码,里面有代码。文件名就是utf8.c

论坛徽章:
0
6 [报告]
发表于 2009-05-14 21:11 |只看该作者
原帖由 Cloud.D.Ace 于 2009-5-14 17:22 发表
非unix环境,不可以使用iconv.h吧?
最好是纯c的



刚接触C,就有这么深刻地认识,真是不简单呀.

论坛徽章:
1
2017金鸡报晓
日期:2017-01-10 15:19:56
7 [报告]
发表于 2009-05-14 21:16 |只看该作者
google 下应该很多
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP