2021-05-12 14:32:11
使用iconv進行編碼gb2312轉utf8 轉碼失敗及解決
使用背景
專案中使用thrift進行C#程式呼叫c++介面,其中的協定是通過json進行傳輸的,由於預設thrift使用utf8進行傳輸,而C#和c++程式都預設使用多位元組的編碼方式,所以在傳輸前就需要對編碼進行utf8的轉換,而在接收處理的時候再轉換成gb2312。
問題
bug發生在一個檔案路徑上面,包含檔案路徑就會導致c++端無法解析,但是純中文和英文及不同字元都沒有問題,所以一開始未懷疑是編碼問題,經過偵錯最終確定問題在iconv轉碼上,在轉碼的時候轉換失敗,導致返回結果為空。
分析
檔名為"1癵鰢⑷}·ˇ々.mp4",其中包含有特殊漢字和字元,猜測為字元集無法表示導致轉碼失敗。
解決
網上查詢確實存在該問題,建議將編碼gb2312換成 gb18030 以支援更多字元。
原來的轉碼函數
std::string ConvertCode::gbk2utf8(const std::string& strGbk)
{
return code_convert("gb2312", "utf-8", strGbk);
}
轉變以後測試正常
std::string ConvertCode::gbk2utf8(const std::string& strGbk)
{
return code_convert("gb18030", "utf-8", strGbk);
}
附iconv轉變函數
std::string ConvertCode::code_convert(char *source_charset, char *to_charset, const std::string& sourceStr)
{
iconv_t cd = iconv_open(to_charset, source_charset);//獲取轉換控制代碼,void*型別
if (cd == 0)
return "";
size_t inlen = sourceStr.size();
if (inlen == 0)
return "";
size_t outlen = inlen*2+1;
const char* inbuf = (char*)sourceStr.c_str();
char* outbuf = (char*)malloc(outlen);
memset(outbuf, 0, outlen);
char *poutbuf = outbuf; //多加這個轉換是為了避免iconv這個函數出現char(*)[255]型別的實參與char**型別的形參不相容
if (iconv(cd, &inbuf, &inlen, &poutbuf, &outlen) == -1)
return "";
std::string strTemp(outbuf);//此時的strTemp為轉換編碼之後的字串
iconv_close(cd);
return strTemp;
}
相關文章