跨平台字符编码转换GBK、UTF8

跨平台字符编码转换GBK、UTF8,第1张

跨平台字符编码转换GBK、UTF8
 #if (defined _WIN32 || defined _WIN64)
# include <windows.h>
# include <stdio.h>
# include <ctype.h>
#elif defined(__linux__)
# include <iconv.h>
# include <wctype.h>
# include <wchar.h>
# include <errno.h>
#endif using namespace std; //代码页
#define CP_GBK 936
#define CP_UTF8 65001 std::wstring s2ws(const std::string str, int code_page);
std::string ws2s(const std::wstring wstr, int code_page); //默认的输出字符串字节长度
//经测试发现OUT_LEN = 10 每次可转3个汉字
const int OUT_LEN = ; /** @fn wstring s2ws(const string str, int code_page)
* @brief 从多字节字符串转为宽字符串
* @param str 源字符串
* @param code_page 要使用的代码页
* @return 成功返回宽字符串,失败返回空字符串
*/
wstring s2ws(const string str, int code_page)
{
wstring wstr_dest;
if (str.size() == )
{
return wstr_dest;
}
wchar_t* wcs = NULL;
#ifdef _MSC_VER
//要转换的多字节字符串
int size = MultiByteToWideChar(code_page, , str.c_str(), -, NULL, );
wcs = new(std::nothrow)wchar_t[size];
if (wcs == NULL)
{
return wstr_dest;
}
if (MultiByteToWideChar(code_page, , str.c_str(), -, wcs, size) == )
{
wstr_dest.clear();
}
else
{
wstr_dest += wcs;
}
delete[] wcs; #elif defined __linux
//申请临时缓冲区,用于保存转换后的字符串
wcs = new(std::nothrow)wchar_t[OUT_LEN];
if (wcs == NULL)
{
return wstr_dest;
}
iconv_t handle = (void*)-;
switch (code_page)
{
case CP_GBK:
handle = iconv_open("UCS-4", "GBK");
break;
case CP_UTF8:
handle = iconv_open("UCS-4", "UTF-8");
break;
default:
//不支持
break;
}
if (handle == (void*)-)
{
delete[] wcs;
return wstr_dest;
} size_t nsrc = str.size()*sizeof(char);
char* src = (char*)str.c_str();
wchar_t* tmp = wcs;
size_t ndst = OUT_LEN * sizeof(wchar_t);
//需多次转换,直到转换完毕
while (nsrc>)
{
memset(wcs, , OUT_LEN*sizeof(wchar_t));
tmp = wcs;
ndst = OUT_LEN * sizeof(wchar_t);
if (iconv(handle, (char**)&src, &nsrc, (char**)&tmp, &ndst) ==(size_t)- && errno != E2BIG)
{
wstr_dest.clear();
break;
}
wstr_dest += wstring(wcs, OUT_LEN - ndst/sizeof(wchar_t));
}
iconv_close(handle);
//释放临时缓冲区
delete[] wcs; #endif
return wstr_dest;
} /** @fn string ws2s(const wstring wstr, int code_page)
* @brief 从宽字符串转为多字节字符串
* @param wstr 源字符串
* @param code_page 要使用的代码页
* @return 成功返回多字节字符串,失败返回空字符串
*/
string ws2s(const wstring wstr, int code_page)
{
string str_dest;
if (wstr.size() == )
{
return str_dest;
}
char *mbs = NULL;
#ifdef _MSC_VER
int size = WideCharToMultiByte(code_page, , wstr.c_str(), -, NULL, , NULL, NULL);
mbs = new(std::nothrow) char[size];
if (NULL == mbs)
{
return str_dest;
}
if ( == WideCharToMultiByte(code_page, , wstr.c_str(), -, mbs, size, NULL, NULL))
{
str_dest.clear();
}
else
{
str_dest += mbs;
}
delete[] mbs;
#elif defined __linux
//申请临时缓冲区,用于保存转换后的字符串
mbs = new(std::nothrow)char[OUT_LEN];
if (NULL == mbs)
{
return str_dest;
}
iconv_t handle = (void*)-;
switch (code_page)
{
case CP_GBK:
handle = iconv_open("GBK", "UCS-4");
break;
case CP_UTF8:
handle = iconv_open("UTF-8", "UCS-4");
break;
default:
//不支持
break;
}
if (handle == (void*)-)
{
delete[] mbs;
return str_dest;
} size_t nsrc = wstr.size() * sizeof(wchar_t);
wchar_t* src = (wchar_t*)wstr.c_str();
char* tmp = NULL;
size_t ndst = OUT_LEN;
//需多次转换,直到转换完毕
while (nsrc>)
{
memset(mbs, , OUT_LEN);
tmp = mbs;
ndst = OUT_LEN;
if (iconv(handle, (char**)&src, &nsrc, (char**)&tmp, &ndst) ==(size_t)- && errno != E2BIG)
{
str_dest.clear();
break;
}
str_dest += string(mbs, OUT_LEN - ndst);
}
iconv_close(handle);
//释放临时缓冲区
delete[] mbs; #endif
return str_dest;
} /** @fn string utf82gbk(const string str_utf8)
* @brief 从UTF-8字符串转为GBK字符串
* @param str_utf8 源字符串
* @return 成功返回GBK字符串,失败返回空字符串
*/
string utf82gbk(const string str_utf8)
{
string str_gbk;
#ifdef _MSC_VER
wstring wstr = s2ws(str_utf8, CP_UTF8);
str_gbk = ws2s(wstr, CP_GBK);
#elif defined __linux
//申请临时缓冲区,用于保存转换后的字符串
char* gbk = new(std::nothrow)char[OUT_LEN];
if (NULL == gbk)
{
return str_gbk;
}
iconv_t handle = iconv_open("GBK", "UTF-8");
if (handle == (void*)-)
{
delete[] gbk;
return str_gbk;
}
size_t nsrc = str_utf8.size();
char* src = (char*)str_utf8.c_str();
char* tmp = NULL;
size_t ndst = OUT_LEN;
//需多次转换,直到转换完毕
while (nsrc > )
{
memset(gbk, , OUT_LEN);
tmp = gbk;
ndst = OUT_LEN;
if (iconv(handle, (char**)&src, &nsrc, (char**)&tmp, &ndst) ==(size_t)- && errno != E2BIG)
{
str_gbk.clear();
break;
}
str_gbk += string(gbk, OUT_LEN - ndst);
}
iconv_close(handle);
//释放临时缓冲区
delete[] gbk;
#endif
return str_gbk;
} /** @fn string gbk2utf8(const string str_gbk)
* @brief 从GBK字符串转为UTF-8字符串
* @param str_gbk 源字符串指针
* @return 成功返回UTF-8字符串,失败返回空字符串
*/
string gbk2utf8(const string str_gbk)
{
string str_utf8;
#ifdef _MSC_VER
wstring wstr = s2ws(str_gbk, CP_GBK);
str_utf8 = ws2s(wstr, CP_UTF8);
#elif defined __linux
//申请临时缓冲区,用于保存转换后的字符串
char* utf8 = new(std::nothrow)char[OUT_LEN];
if (NULL == utf8)
{
return str_utf8;
}
iconv_t handle = iconv_open("UTF-8", "GBK");
if (handle == (void*)-)
{
delete[] utf8;
return str_utf8;
}
size_t nsrc = str_gbk.size();
char* src = (char*)str_gbk.c_str();
char* tmp = NULL;
size_t ndst = OUT_LEN;
//需多次转换,直到转换完毕
while (nsrc > )
{
memset(utf8, , OUT_LEN);
tmp = utf8;
ndst = OUT_LEN;
if (iconv(handle, (char**)&src, &nsrc, (char**)&tmp, &ndst) ==(size_t)- && errno != E2BIG)
{
str_utf8.clear();
break;
}
str_utf8 += string(utf8, OUT_LEN - ndst);
}
iconv_close(handle);
//释放临时缓冲区
delete[] utf8;
#endif
return str_utf8;
} //wchar_t转成UTF-8
int Wchar2Utf8Convert( const wchar_t* a_szSrc, char* a_szDest, int a_nDestSize )
{
#if (defined _WIN32 || defined _WIN64)
return WideCharToMultiByte( CP_UTF8, , a_szSrc, -, a_szDest, a_nDestSize, NULL, NULL );
#elif defined(__linux__)
size_t result;
size_t srcSize = (wcslen(a_szSrc)+)*sizeof(wchar_t);
iconv_t env;
env = iconv_open("UTF-8","WCHAR_T");
if (env==(iconv_t)-)
{
//printf("iconv_open WCHAR_T->UTF8 error%s %d/n",strerror(errno),errno) ;
return ;
}
size_t buf_count = a_nDestSize;
result = iconv(env,(char**)&a_szSrc,(size_t*)&srcSize,(char**)&a_szDest,(size_t*)&buf_count);
if (result==(size_t)-)
{
//printf("iconv WCHAR_T->UTF8 error %d/n",errno) ;
return ;
}
iconv_close(env);
return (int)result;
#endif
} //UTF-8转成wchar_t
int Utf82WcharConvert( const char* a_szSrc, wchar_t* a_szDest, int a_nDestSize )
{
#if (defined _WIN32 || defined _WIN64)
return MultiByteToWideChar( CP_UTF8, , a_szSrc, -, a_szDest, a_nDestSize );
#elif defined(__linux__)
size_t result;
iconv_t env;
size_t size = strlen(a_szSrc)+ ;
env = iconv_open("WCHAR_T","UTF-8");
if (env==(iconv_t)-)
{
//printf("iconv_open UTF8->WCHAR_T error %d/n",errno) ;
return ;
}
size_t buf_count = a_nDestSize*sizeof(wchar_t);
result = iconv(env,(char**)&a_szSrc,(size_t*)&size,(char**)&a_szDest,(size_t*)&buf_count);
if (result==(size_t)-)
{
//printf("iconv UTF8->WCHAR_T error %d/n",errno) ;
return ;
}
iconv_close(env);
return (int)result; #endif
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/588431.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-12
下一篇 2022-04-12

发表评论

登录后才能评论

评论列表(0条)

保存