OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2665|回复: 0

兼容原子哥 UTF8 字符转 GBK

[复制链接]

2

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
60
金钱
60
注册时间
2018-8-7
在线时间
8 小时
发表于 2018-8-25 18:06:28 | 显示全部楼层 |阅读模式
本帖最后由 Kimalittlestar 于 2018-8-25 18:08 编辑

最近想做一个 网络天气的小东西.好容易写好了驱动,GET 了一下天气网站的 API 返回竟然是中文乱码,猜测是 UTF8 乱码,果不其然.于是就自己去寻找网上大神们的解决方案:一般是 UTF-8 -> Unicode  ->GBK (中文)
关键字: stm32103 嵌入式 utf8 GBK 乱码 单片机
fatfas 中的库文件中有 GBK <=>Unicode 的 库函数 原子哥也有提供GBK 的码表 所以就自己写了一个框,总结发上来
同时以防自己以后还需要用到 GBK -> UTF8 的时候 可以逆向 回推.
感谢 csdn @bladeandmaster88 的分享 以下是原链接
https://blog.csdn.net/bladeandmaster88/article/details/54837338
以下是代码

[mw_shl_code=c,true]/**********************************************************************************
* 函数名称: StrProcess_UTF8toGBK
* 函数功能: 将网络上 utf8 的字符串转换为 GBK 字符串 使得兼容 原子LCD屏驱动程序
* 函数输入: void input: c_utf8 原utf8 字符串 同时 新的 gbk字符串会将其覆盖
*                       length 你想要设置的 中间缓存块的大小
* 函数输出: void output:字符总数 (一个中文算两个字节)
* 作者 :authorKim_alittle_star
* 文件依存:
*   #include "ff.h"
*   #include "malloc.h"
*   #include "stm32f10x.h"
**********************************************************************************/
u16 StrProcess_UTF8toGBK(u8* c_utf8,u16 length)
{
//  ff_uni2oem(,FF_CODE_PAGE);
    /* !< 首先 将 utf8 转换成标准 Unicode 然后查表将 Unicode 转化为GBK */
    u16 outputSize = 0; //记录转换后的gbk字符串长度
    u8 * pInput = c_utf8;
    u8* c_gbk = mymalloc(0,length);  /* !< 申请内存,也可以外部传入一个 数据缓存空间 */
    u8* pOutput = c_gbk;
    u16* uni = (u16*)c_gbk;
    u16 gbk;
    /* !< 以下中间代码来自于 CSDN @bladeandmaster88 公开的源码 */
    while (*pInput)
    {
        if (*pInput > 0x00 && *pInput <= 0x7F) //处理单字节UTF8字符(英文字母、数字)
        {
            *pOutput = *pInput;
             pOutput+= 1;
            *pOutput = 0; //小端法表示,在高地址填补0
        }
        else if (((*pInput) & 0xE0) == 0xC0) //处理双字节UTF8字符
        {
            char high = *pInput;
            pInput+=1;
            char low = *pInput;
            if ((low & 0xC0) != 0x80)  //检查是否为合法的UTF8字符表示
            {
                return -1; //如果不是则报错
            }

            *pOutput = (high << 6) + (low & 0x3F);
            pOutput++;
            *pOutput = (high >> 2) & 0x07;
        }
        else if (((*pInput) & 0xF0) == 0xE0) //处理三字节UTF8字符
        {
            char high = *pInput;
            pInput++;
            char middle = *pInput;
            pInput++;
            char low = *pInput;
            if (((middle & 0xC0) != 0x80) || ((low & 0xC0) != 0x80))
            {
                return -1;
            }
            *pOutput = (middle << 6) + (low & 0x3F);//取出middle的低两位与low的低6位,组合成unicode字符的低8位
            pOutput++;
            *pOutput = (high << 4) + ((middle >> 2) & 0x0F); //取出high的低四位与middle的中间四位,组合成unicode字符的高8位
        }
        else //对于其他字节数的UTF8字符不进行处理
        {
            return -1;
        }
        pInput++;//处理下一个utf8字符
        pOutput++;
    }
    //unicode字符串后面,有两个\0
    *pOutput = 0;
     pOutput++;
    *pOutput = 0;
    /* !< 感谢 @bladeandmaster88 的开源支持 */
    pInput = c_utf8;
    while(*uni != 0)
    {
        gbk = ff_uni2oem(*uni,FF_CODE_PAGE);        /* !< Unicode 向 GBK 转换函数  */
        uni++;
        if(gbk&0xff00)
        {
            *pInput = ((gbk&0xff00)>>8);
            pInput++;
            *pInput = (gbk&0x00ff);
            pInput++;
            outputSize += 2;
        }else
        {
            *pInput = (gbk&0x00ff);
            pInput++;
            outputSize++;
        }


    }
    *pInput = '\0';         /* !< 加上结束符号 */
    myfree(0,c_gbk);        /* !< 释放内存 */
    return outputSize;

}
[/mw_shl_code]




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-19 00:11

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表