[C/C++]_[utf8字符串转换为unicode字符串]

来源:互联网 发布:海关数据米课 编辑:程序博客网 时间:2024/05/22 17:07


场景:

1.windows下需要unicode来处理非ascii的字符,如中文文件路径.

2.但是做字符串处理时又需要转换成中间的utf8处理,这就涉及到了互转.

3.参考unicode和utf8关系:


http://baike.baidu.com/view/40801.htm


文件:test_utf82unicode.cpp(只做了支持双字节的unicode转码.)

#include <stdio.h>#include <assert.h>#include <string.h>#include <stdlib.h>void OneUTF82Unicode(const char* utf_char, char* unicode_char);char* utf82unicode(const char* utf,size_t *unicode_number){        char* utf8 = strdup(utf);    size_t utf8_length = strlen(utf8);     //这里可以自己考虑实现更精确的大小.    //+2是留两个00.    char* unicode = (char*)malloc(utf8_length*2+2);    memset(unicode,0,utf8_length*2+2);    size_t index  = 0;    size_t start = 0;    unsigned char temp;    //10000000=0x80 1110=0xE 110=0x6    unsigned char flag = 0;    size_t unicode_index = 0;    bool is_finded = false;    while((temp = utf8[index]))    {        start = index;        temp = temp >> 4 ;        if(temp > 0xE)        {            assert(0);            printf("utf8 bigger than 4 byte is not supported.\n");            break;        }        if(temp == 0xE)        {            index+=3;            is_finded = true;        }        temp = temp >> 1;        if(!is_finded && temp == 0x6)        {            index+=2;            is_finded = true;        }        temp = temp >> 2;        if(!is_finded && temp == 0x00)        {            index+=1;            is_finded = true;        }        if(index > utf8_length)        {            break;        }        flag = utf8[index];        utf8[index] = 0;        OneUTF82Unicode(utf8+start,unicode+unicode_index);        utf8[index] = flag;        unicode_index+=2;        is_finded = false;    }    free(utf8);    *unicode_number = unicode_index/2;    return unicode;}void OneUTF82Unicode(const char* utf_char, char* unicode_char){    //unicode: 0x192->110010010 ,utf8:0xC692->11000110|10010010    //小端序    int utf_length = strlen(utf_char);    //0x3F->00111111    switch(utf_length)    {        case 1:             unicode_char[0] = utf_char[0];            unicode_char[1] = 0;            break;        case 2:             unicode_char[0] = (utf_char[1] & 0x3F) | ((utf_char[0] & 0x3) << 6);            unicode_char[1] = (utf_char[0] & 0x3C) >> 2;            break;        case 3:             unicode_char[0] = (utf_char[2] & 0x3F) | ((utf_char[1] & 0x3) << 6);            unicode_char[1] = ((utf_char[1] & 0x3C) >> 2) | ((utf_char[0] & 0xF) << 4);            break;        default:            assert(0);            printf("utf_char length is bigger than 4 unsupported.\n");            break;    }}int main(int argc, char *argv[]){    printf("Hello, world\n");    char utf_char[12] = {0xC3,0xBE};    memset(utf_char+2,0,10);    char unicode_char[3] = {0,0,0};    OneUTF82Unicode(utf_char,unicode_char);    printf("%x,%x\n",(unsigned char)unicode_char[0],unicode_char[1]);    utf_char[0] = 0xE6;    utf_char[1] = 0x88;    utf_char[2] = 0x91;    OneUTF82Unicode(utf_char,unicode_char);    printf("%x,%x\n",(unsigned char)unicode_char[0],unicode_char[1]);    size_t unicode_number = 0;    char utf_str[]={0xC3,0xBE,0xE6,0x88,0x91,0xE4,0xBB,0xAC,0xE7,0x9A,0x84,0xE5,0x9B,        0xBD,0xE5,0xAE,0xB6,0x64,0x61,0xE7,0x9A,0x84,0xE5,0x93,0xA6};    char* unicode = utf82unicode(utf_str,&unicode_number);        printf("%d\n",unicode_number);    size_t index = 0;    for(size_t i=0;i<unicode_number;++i,index+=2)    {        printf("%x,%x\n",(unsigned char)unicode[index],(unsigned char)unicode[index+1]);            }    free(unicode);    return 0;}


输出:

Hello, worldfe,011,6210fe,011,62ec,4e84,76fd,56b6,5b64,061,084,76e6,54


原创粉丝点击