utf8 to unicode

Unicode与UTF-8转换
本文提供了一段C语言代码示例,展示了如何实现Unicode编码与UTF-8编码之间的相互转换,并通过示例演示了这一过程。代码中包括了转换函数、打印函数以及主函数用于验证转换效果。

#include <stdio.h>

#include <string.h>

#include <malloc.h>

#include <memory.h>

 

#ifdef WIN32

#define uint8_t  unsigned __int8

#define uint16_t unsigned __int16

#define uint32_t unsigned __int32

#define uint64_t unsigned __int64

 

#define int8_t  __int8

#define int16_t __int16

#define int32_t __int32

#endif

 

int unicode_to_utf8(uint16_t *in, int insize, uint8_t **out)

{

    int i = 0;

    int outsize = 0;

    int charscount = 0;

    uint8_t *result = NULL;

    uint8_t *tmp = NULL;

 

    charscount = insize / sizeof(uint16_t);

    result = (uint8_t *)malloc(charscount * 3 + 1);

    memset(result, 0, charscount * 3 + 1);

    tmp = result;

 

    for (i = 0; i < charscount; i++)

    {

        uint16_t unicode = in[i];

 

        if (unicode >= 0x0000 && unicode <= 0x007f)

        {

            *tmp = (uint8_t)unicode;

            tmp += 1;

            outsize += 1;

        }

        else if (unicode >= 0x0080 && unicode <= 0x07ff)

        {

            *tmp = 0xc0 | (unicode >> 6);

            tmp += 1;

            *tmp = 0x80 | (unicode & (0xff >> 2));

            tmp += 1;

            outsize += 2;

        }

        else if (unicode >= 0x0800 && unicode <= 0xffff)

        {

            *tmp = 0xe0 | (unicode >> 12);

            tmp += 1;

            *tmp = 0x80 | (unicode >> 6 & 0x00ff);

            tmp += 1;

            *tmp = 0x80 | (unicode & (0xff >> 2));

            tmp += 1;

            outsize += 3;

        }

 

    }

 

    *tmp = '/0';

    *out = result;

    return 0;

}

 

int utf8_to_unicode(uint8_t *in, uint16_t **out, int *outsize)

{

    uint8_t *p = in;

    uint16_t *result = NULL;

    int resultsize = 0;

    uint8_t *tmp = NULL;

 

    result = (uint16_t *)malloc(strlen(in) * 2 + 2); /* should be enough */

    memset(result, 0, strlen(in) * 2 + 2);

    tmp = (uint8_t *)result;

 

    while(*p)

    {

        if (*p >= 0x00 && *p <= 0x7f)

        {

            *tmp = *p;

            tmp++;

            *tmp = '/0';

            resultsize += 2;

        }

        else if ((*p & (0xff << 5))== 0xc0)

        {

            uint16_t t = 0;

            uint8_t t1 = 0;

            uint8_t t2 = 0;

 

            t1 = *p & (0xff >> 3);

            p++;

            t2 = *p & (0xff >> 2);

 

            *tmp = t2 | ((t1 & (0xff >> 6)) << 6);//t1 >> 2;

            tmp++;

 

            *tmp = t1 >> 2;//t2 | ((t1 & (0xff >> 6)) << 6);

            tmp++;

 

            resultsize += 2;

        }

        else if ((*p & (0xff << 4))== 0xe0)

        {

            uint16_t t = 0;

            uint8_t t1 = 0;

            uint8_t t2 = 0;

            uint8_t t3 = 0;

 

            t1 = *p & (0xff >> 3);

            p++;

            t2 = *p & (0xff >> 2);

            p++;

            t3 = *p & (0xff >> 2);

 

            //Little Endian

            *tmp = ((t2 & (0xff >> 6)) << 6) | t3;//(t1 << 4) | (t2 >> 2);

            tmp++;

 

            *tmp = (t1 << 4) | (t2 >> 2);//((t2 & (0xff >> 6)) << 6) | t3;

            tmp++;

            resultsize += 2;

        }

 

        p++;

    }

 

    *tmp = '/0';

    tmp++;

    *tmp = '/0';

    resultsize += 2;

 

    *out = result;

    *outsize = resultsize; 

    return 0;

}

 

void dump_utf8(uint8_t *utf8)

{

    uint8_t *p = utf8;

 

    while(*p)

    {

        printf("%02X", *p);

        p++;

    }

    putchar('/n');

}

 

void dump_unicode(uint16_t *utf16, int size)

{

    uint8_t *p = (uint8_t *)utf16;

    int i = 0;

 

    for (i = 0; i < size; i++)

    {

        printf("%02X", *p);

        p++;

    }

    putchar('/n');

}

 

int main()

{

    uint16_t unicode[] = L"中文";

    uint8_t *utf8 = NULL;

 

    int unisize = 0;

    uint16_t *uni = NULL;

 

    printf("original unicode: /n");

    dump_unicode(unicode, sizeof(unicode));

 

    printf("converted to utf8: /n");

    unicode_to_utf8(unicode, sizeof(unicode), &utf8);

    dump_utf8(utf8);

 

    printf("converted to unicode: /n");

    utf8_to_unicode(utf8, &uni, &unisize);

    dump_unicode(uni, unisize);

 

    free(utf8);

    free(uni);

 

    return 0;

}

// 城乡划分代码 struct CXHFCODE { //行政区划代码 CString xzqhdm; // 行政区划名称 CString xzqhmc; // 行政区划全称 CString xzqhqc; // 行政区划级别 CString xzqhjb; // 省直辖市代码 CString szxsdm; // 省直辖市名称 CString szxsmc; // 市级代码 CString sjdm; // 市级名称 CString sjmc; // 区级代码 CString qjdm; // 区级名称 CString qjmc; // 镇街道代码 CString zjddm; // 镇街道名称 CString zjdmc; // 村居委会代码 CString cjwhdm; // 村居委会名称 CString cjwhmc; // 城乡划分代码 CString cxhfdm; }; 省直辖市名称 市级名称 区级名称 镇街道名称 村居委会名称 这六级对应的是 省、地市、县、乡、社区/村委会六级行政区划, | CXHFCODE data; while (sqlite3_step(stmt) == SQLITE_ROW) { CXHFCODE data; //行政区划代码 data.xzqhdm = UTF8ToUnicode((const char*)(char*)sqlite3_column_text(stmt, 0)); // 行政区划名称 data.xzqhmc = UTF8ToUnicode((const char*)(char*)sqlite3_column_text(stmt, 1)); // 行政区划全称 data.xzqhqc = UTF8ToUnicode((const char*)(char*)sqlite3_column_text(stmt, 2)); // 行政区划级别 data.xzqhjb = UTF8ToUnicode((const char*)(char*)sqlite3_column_text(stmt, 3)); // 省直辖市代码 data.szxsdm = UTF8ToUnicode((const char*)(char*)sqlite3_column_text(stmt, 4)); // 省直辖市名称 data.szxsmc = UTF8ToUnicode((const char*)(char*)sqlite3_column_text(stmt, 5)); // 市级代码 data.sjdm = UTF8ToUnicode((const char*)(char*)sqlite3_column_text(stmt, 6)); // 市级名称 data.sjmc = UTF8ToUnicode((const char*)(char*)sqlite3_column_text(stmt, 7)); // 区级代码 data.qjdm = UTF8ToUnicode((const char*)(char*)sqlite3_column_text(stmt, 8)); // 区级名称 data.qjmc = UTF8ToUnicode((const char*)(char*)sqlite3_column_text(stmt, 9)); // 镇街道代码 data.zjddm = UTF8ToUnicode((const char*)(char*)sqlite3_column_text(stmt, 10)); // 镇街道名称 data.zjdmc = UTF8ToUnicode((const char*)(char*)sqlite3_column_text(stmt, 11)); // 村居委会代码 data.cjwhdm = UTF8ToUnicode((const char*)(char*)sqlite3_column_text(stmt, 12)); // 村居委会名称 data.cjwhmc = UTF8ToUnicode((const char*)(char*)sqlite3_column_text(stmt, 13)); // 城乡划分代码 data.cxhfdm = UTF8ToUnicode((const char*)(char*)sqlite3_column_text(stmt, 14)); cxhfcodeVec_.push_back(data); } std::map<CString, std::map<CString, std::map<CString, std::map<CString, std::map<CString, CString>>>>> regions_; while 循环时如何把data数据插入到regions_中,请写一下
最新发布
07-10
为了将从 SQLite 查询得到的行政区划数据插入到 `std::map<CString, std::map<CString, std::map<CString, std::map<CString, std::map<CString, CString>>>>>` 数据结构中,需要在每次执行查询结果遍历时提取字段并逐层构建嵌套映射关系。 SQLite 查询使用 `sqlite3_step` 逐行获取结果集,每行对应一条行政区划记录[^1]。通过 `sqlite3_column_text` 获取每个字段的 UTF-8 编码字符串,并转换为 Unicode 字符串以适配 `CString` 类型[^3]。然后,依次填充省、市、区、镇、村等层级信息到嵌套 `std::map` 中。 ### 示例代码 以下代码展示如何将查询结果插入到五层嵌套的 `std::map` 结构中: ```cpp std::map<CString, std::map<CString, std::map<CString, std::map<CString, std::map<CString, CString>>>>> administrativeMap; while (sqlite3_step(stmt) == SQLITE_ROW) { // 提取字段值并转为Unicode CString province = UTF8ToUnicode((const char*)sqlite3_column_text(stmt, 0)); CString city = UTF8ToUnicode((const char*)sqlite3_column_text(stmt, 1)); CString district = UTF8ToUnicode((const char*)sqlite3_column_text(stmt, 2)); CString town = UTF8ToUnicode((const char*)sqlite3_column_text(stmt, 3)); CString village = UTF8ToUnicode((const char*)sqlite3_column_text(stmt, 4)); // 构建五级嵌套map结构 administrativeMap[province][city][district][town][village] = village; } ``` 上述代码中,每一层 `std::map` 对应一个行政区划级别,例如 `administrativeMap["广东省"]` 表示该省下的所有城市,而 `administrativeMap["广东省"]["广州市"]` 表示广州市下辖的所有区,依此类推。最终 `administrativeMap["广东省"]["广州市"]["天河区"]["石牌桥镇"]["石牌社区"]` 存储的是村委会或居委会名称。 ### 插入策略说明 - **逐层构建**:每次访问 `map[key]` 时,如果该键不存在则会自动创建一个新的子 `map`。 - **避免重复插入**:若存在相同路径的记录,最后一次插入的值会覆盖之前的值。 - **灵活性**:支持任意层级的缺失,例如可以仅插入省级和市级数据而不包含区县信息。 ### 遍历与查询操作 遍历整个结构可以使用多层嵌套循环,逐层输出省、市、区、镇、村信息。查询特定行政区划时,可通过链式访问实现快速定位: ```cpp if (administrativeMap.find(_T("广东省")) != administrativeMap.end() && administrativeMap[_T("广东省")].find(_T("广州市")) != administrativeMap[_T("广东省")].end() && administrativeMap[_T("广东省")][_T("广州市")].find(_T("天河区")) != administrativeMap[_T("广东省")][_T("广州市")].end() && administrativeMap[_T("广东省")][_T("广州市")][_T("天河区")].find(_T("石牌桥镇")) != administrativeMap[_T("广东省")][_T("广州市")][_T("天河区")].end() && administrativeMap[_T("广东省")][_T("广州市")][_T("天河区")][_T("石牌桥镇")].find(_T("石牌社区")) != administrativeMap[_T("广东省")][_T("广州市")][_T("天河区")][_T("石牌桥镇")].end()) { CString committee = administrativeMap[_T("广东省")][_T("广州市")][_T("天河区")][_T("石牌桥镇")][_T("石牌社区")]; std::wcout << "社区/村委会: " << CW2A(committee.GetString()) << std::endl; } else { std::wcout << "未找到指定的行政区划" << std::endl; } ``` 这种结构便于管理复杂的行政区划数据,并且支持高效的查询和更新操作。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值