字符集是对特定语言中所有可读或可显示字符的称呼。例如英语、汉语、日语等都是不同的字符集。字符集决定了可以展示和表示的字符范围。在字符集中,需要使用编码字符集来实现字符的编码和转码。编码字符集使用编码值来表示字符在字库表中的位置。字库表是一个包含了所有可读或可显示字符的数据库,它决定了字符集能够展示的所有字符的范围。字符编码定义了编码字符集和实际存储数值之间的转换关系。常见的字符编码方式包括ASCII、ISO 8859-1、GB2312、GBK等。常情况下,一个字符集对应一个编码方式,比如ASCII、ISO 8859-1、GB2312、GBK等都是针对特定字符集的编码方式。
然而,一个字符集也可以有多种编码方式。例如,UCS字符集(也是Unicode使用的字符集)上有UTF-8、UTF-16、UTF-32等编码方式。
iconv
#include <iostream>
#include <string>
#include <string.h>
#include <stdlib.h>
using namespace std;
#ifdef _WIN32
#include <windows.h>
string GbkToUtf8(const char *src_str)
{
int len = MultiByteToWideChar(CP_ACP, 0, src_str, -1, NULL, 0);
wchar_t* wstr = new wchar_t[len + 1];
memset(wstr, 0, len + 1);
MultiByteToWideChar(CP_ACP, 0, src_str, -1, wstr, len);
len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
char* str = new char[len + 1];
memset(str, 0, len + 1);
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
string strTemp = str;
if (wstr) delete[] wstr;
if (str) delete[] str;
return strTemp;
}
string Utf8ToGbk(const char *src_str)
{
int len = MultiByteToWideChar(CP_UTF8, 0, src_str, -1, NULL, 0);
wchar_t* wszGBK = new wchar_t[len + 1];
memset(wszGBK, 0, len * 2 + 2);
MultiByteToWideChar(CP_UTF8, 0, src_str, -1, wszGBK, len);
len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
char* szGBK = new char[len + 1];
memset(szGBK, 0, len + 1);
WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL);
string strTemp(szGBK);
if (wszGBK) delete[] wszGBK;
if (szGBK) delete[] szGBK;
return strTemp;
}
int GbkToUtf8(char *str_str, size_t src_len, char *dst_str, size_t dst_len)
{
iconv_t cd;
char **pin = &str_str;
char **pout = &dst_str;
cd = iconv_open("utf8", "gbk");
if (cd == 0)
return -1;
memset(dst_str, 0, dst_len);
if (iconv(cd, pin, &src_len, pout, &dst_len) == -1)
return -1;
iconv_close(cd);
*pout = '\0';
return 0;
}
int Utf8ToGbk(char *src_str, size_t src_len, char *dst_str, size_t dst_len)
{
iconv_t cd;
char **pin = &src_str;
char **pout = &dst_str;
cd = iconv_open("gbk", "utf8");
if (cd == 0)
return -1;
memset(dst_str, 0, dst_len);
if (iconv(cd, pin, &src_len, pout, &dst_len) == -1)
return -1;
iconv_close(cd);
*pout = '\0';
return 0;
}
int main(void)
{
char *src_str = "您好世界,hello";
cout << "origin string: " << src_str << endl;
// windows default is gbk
string dst_str = GbkToUtf8(src_str);
cout << "gbk to utf8: " << dst_str << endl;
string str_utf8 = Utf8ToGbk(dst_str.c_str());
cout << "utf8 to gbk: " << str_utf8 << endl;
// unix default is utf8
char dst_gbk[1024] = {0};
Utf8ToGbk(src_str, strlen(src_str), dst_gbk, sizeof(dst_gbk));
cout << "utf8 to gbk: " << dst_gbk << endl;
char dst_utf8[1024] = {0};
GbkToUtf8(dst_gbk, strlen(dst_gbk), dst_utf8, sizeof(dst_utf8));
cout << "gbk to utf8: " << dst_utf8 << endl;
return 0;
}
GbkToUtf8
函数和 Utf8ToGbk
函数分别实现了在 Windows 平台下的 GBK 转 UTF-8 和 UTF-8 转 GBK 的功能。GbkToUtf8
函数使用了 Windows API 中的 MultiByteToWideChar
和 WideCharToMultiByte
来进行编码的转换。Utf8ToGbk
函数同样使用了 Windows API 中的 MultiByteToWideChar
和 WideCharToMultiByte
来进行编码的转换。GbkToUtf8
函数的另一种实现方式是使用了 iconv
函数,可以实现不同平台下的编码转换。Utf8ToGbk
函数也使用了 iconv
函数进行编码转换。
Utf8ToGbk
函数接受四个参数,分别是源字符串指针src_str
、源字符串长度src_len
、目标字符串指针dst_str
以及目标字符串长度dst_len
。首先定义了一个
iconv_t
类型的变量cd
,用于表示一个字符转换的描述符。通过
iconv_open("gbk", "utf8")
打开一个从 UTF-8 到 GBK 的转换描述符,并将其赋值给cd
。如果打开失败,返回 -1。使用
iconv
函数进行实际的编码转换,将源字符串的内容从 UTF-8 转换为 GBK,并将结果存储到目标字符串中。在转换之前,先使用
memset
将目标字符串清零,避免之前可能存在的脏数据影响转换结果。如果转换过程中出现错误,
iconv
函数会返回 -1,并且函数也会返回 -1。最后使用
iconv_close
关闭转换描述符,并将目标字符串末尾设置为 '\0',表示字符串结束。如果转换顺利完成,则函数返回 0,表示转换成功。
函数原型为:
iconv_t iconv_open (const char* tocode, const char* fromcode);
这个函数返回一个把formcode编码的字符串转换成tocode编码的字符串的转换描述符。如果发生错误返回(iconv_t)-1,同时设置errno。
函数原型为:
size_t iconv(iconv_t cd,
char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft);
这个函数利用iconv_open返回的转换描述符执行实际的转换操作。inbuf代表需要转换编码的字符地址,inbytesleft代表需要转换的字符个数地址,outbuf代表需要转换后的字符存放地址,outbytesleft代表存放转换后字符的最大个数地址。这个函数会修改传进来的参数,所以,要用另外用四个变量来表示这个地址。
函数执行失败返回(size_t)-1,errno被设置,否则,返回以不可逆的方式转换的字符个数,可逆转换的字符个数没有统计。
函数原型为:
int iconv_close (iconv_t cd);
这个函数关闭之前调用iconv_open返回的描述符,释放内存空间,如果成功返回0,否则返回-1,errno被设置。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。