1. 程式人生 > >相容正點原子 stm32f103 UTF8字元編碼轉換 GBK 編碼格式

相容正點原子 stm32f103 UTF8字元編碼轉換 GBK 編碼格式

最近想做一個 網路天氣的小東西.好容易寫好了驅動,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
以下是程式碼
/************************************************************************
* 函式名稱: StrProcess_UTF8toGBK
* 函式功能: 將網路上 utf8 的字串轉換為 GBK 字串 使得相容 原子LCD屏驅動程式
* 函式輸入: void input: c_utf8 原utf8 字串 同時 新的 gbk字串會將其覆蓋
* length 你想要設定的 中間快取塊的大小
* 函式輸出: void output:字元總數 (一箇中文算兩個位元組)
* 作者 :author:@Kim_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;

}