#include <string>
#include <set>
#include <windows.h>
namespace ConvertUtil_ICONV {
// 参考:https://baike.baidu.com/item/libiconv/10026740?fr=ge_ala
/*
libiconv库 [1] 为需要做转换的应用提供了一个iconv的函数,以实现一个字符编码到另一个字符编码的转换。
包括的编码有:
欧洲语系
ASCII,
ISO-8859-{1,2,3,4,5,7,9,10,13,14,15,16},
KOI8-R, KOI8-U, KOI8-RU,
CP{1250,1251,1252,1253,1254,1257},
CP{850,866},
Mac{Roman,CentralEurope,Iceland,Croatian,Romania},
Mac{Cyrillic,Ukraine,Greek,Turkish},
Macintosh
犹太语系
ISO-8859-{6,8}, CP{1255,1256}, CP862, Mac{Hebrew,Arabic}
日文
EUC-JP, SHIFT_JIS, CP932, ISO-2022-JP, ISO-2022-JP-2, ISO-2022-JP-1
中文
EUC-CN, HZ, GBK, GB18030, EUC-TW, BIG5, CP950, BIG5-HKSCS, ISO-2022-CN, ISO-2022-CN-EXT
朝鲜文
EUC-KR, CP949, ISO-2022-KR, JOHAB
亚美尼亚语
ARMSCII-8
格鲁尼亚语
Georgian-Academy, Georgian-PS
塔吉克语
KOI8-T
泰国语
TIS-620, CP874, MacThai
老挝语
MuleLao-1, CP1133
越南语
VISCII, TCVN, CP1258
特殊平台
HP-ROMAN8, NEXTSTEP
全部Unicode
UTF-8, UTF-7
UCS-2, UCS-2BE, UCS-2LE, UCS-4, UCS-4BE, UCS-4LE
UTF-16, UTF-16BE, UTF-16LE, UTF-32, UTF-32BE, UTF-32LE
C99, JAVA
*/
// 常用code列表
std::set<std::string> k_set_code =
{
"GP2312",
"GBK",
"BIG5",
"UTF-8",
"EUC-KR",
"SHIFT_JIS",
"ISO8859-1",
// 1~16...
"ISO8859-16"
};
const char* k_iconv_file_name = "libiconv2.dll";
typedef void* iconv_t;
typedef iconv_t (*iconv_open)(const char* tocode, const char* fromcode);
typedef size_t (*iconv)(iconv_t cd, const char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft);
typedef int (*iconv_close)(iconv_t cd);
HMODULE file_handle_ = nullptr;
iconv_open iconv_open_ = nullptr;
iconv iconv_ = nullptr;
iconv_close iconv_close_ = nullptr;
void* GetProcAddress(const char* fun_name)
{
void* fun = nullptr;
fun = ::GetProcAddress(file_handle_, fun_name);
if (nullptr == fun)
{
return nullptr;
}
return fun;
}
bool Init()
{
if (nullptr != file_handle_)
{
return true;
}
file_handle_ = ::LoadLibraryA(k_iconv_file_name);
if (nullptr == file_handle_)
{
return false;
}
iconv_open_ = (iconv_open)GetProcAddress("libiconv_open");
iconv_ = (iconv)GetProcAddress("libiconv");
iconv_close_ = (iconv_close)GetProcAddress("libiconv_close");
return (nullptr != iconv_open_) && (nullptr != iconv_) && (nullptr != iconv_close_);
}
void UnInit()
{
BOOL ret = ::FreeLibrary(file_handle_);
// log...
}
bool Convert(std::string& out_string, const std::string& in_string, const std::string& out_code, const std::string& in_code)
{
bool ret = false;
do
{
ret = Init();
if (!ret)
{
break;
}
iconv_t conv = iconv_open_(out_code.c_str(), in_code.c_str());
if (iconv_t(-1) == conv)
{
ret = false;
break;
}
const char* p_in = in_string.c_str();
size_t in_size = in_string.size() + 1;
size_t out_size = in_string.size() * 4;
char* p_out = new char[out_size];
memset(p_out, 0, out_size);
char* p_out_src = p_out;
size_t out_size_left = out_size;
if (size_t(-1) == iconv_(conv, &p_in, &in_size, &p_out, &out_size_left))
{
delete[] p_out_src;
p_out_src = nullptr;
iconv_close_(conv);
conv = nullptr;
ret = false;
break;
}
ret = true;
out_string.assign(p_out_src, out_size - out_size_left);
delete[] p_out_src;
p_out_src = nullptr;
iconv_close_(conv);
conv = nullptr;
} while (false);
return ret;
}
bool GBKToUTF8(std::string& utf8, const std::string& gbk)
{
return Convert(utf8, gbk, "utf-8", "GB2312");
}
bool UTF8ToGBK(std::string& gbk, const std::string& utf8)
{
return Convert(gbk, utf8, "gbk" , "utf-8");
}
}
int main()
{
std::string ansi = "中国"; // GB2312
std::string utf8;
ConvertUtil_ICONV::GBKToUTF8(utf8, ansi);
ConvertUtil_ICONV::UTF8ToGBK(ansi, utf8);
return 1;
}
字符编码转换实现(基于conv)
最新推荐文章于 2024-01-03 21:50:21 发布