{
int u8Len =WideCharToMultiByte(CP_UTF8, NULL,str,str.GetLength(), NULL, 0, NULL, FALSE);
char* szU8 = new char[u8Len + 1];
int hh=WideCharToMultiByte(CP_UTF8,NULL,str, str.GetLength(), szU8, u8Len, NULL, FALSE);
szU8[u8Len] = '\0';
CString str_utf=CString(szU8);
delete szU8;
return str_utf;
}
将unicode转成utf-8,汉字个数是偶数的时候正常,奇数的时候,最后一个字符就五法实现转码,
比如:我输入“你好”编码之后结果正常
但是”周州林“编码之后的结果就是”周州“
在网上查了WideCharToMultiByte的第四个参数(缓存区的字符个数),在第一次调用这个函数的地方,改成str.GetLength()+1,结果发现奇数个汉字正常了,但是偶数个汉字后面,最后一个汉字后面就加上了一个?,后来该成了str.GetLength()+2
发现他在处理数字和中文字符混合的字符串的字符串时,又出现了问题。
资料:unicode 汉字是2个字节,utf-8 汉字是3个字节。
10 个解决方案
#1
CString str_utf=CString(szU8);
这句是错误的。
这句是错误的。
#2
涉及到utf-8和unicode最好就别用CString了,不明了
下面的函数出去后记得使用delete []释放pOutBuf。
bool UnicodeToUtf8(const wchar_t* buf, char * & pOutBuf)
{
if (buf == NULL)
{
return NULL ;
}
int nLen = ::WideCharToMultiByte (CP_UTF8, 0, buf, -1, NULL, 0, NULL, NULL);
pOutBuf = new char[nLen+1] ;
ZeroMemory (pOutBuf, nLen + 1) ;
::WideCharToMultiByte (CP_UTF8, 0, buf, -1, pOutBuf, nLen, NULL, NULL);
return true;
}
下面的函数出去后记得使用delete []释放pOutBuf。
bool UnicodeToUtf8(const wchar_t* buf, char * & pOutBuf)
{
if (buf == NULL)
{
return NULL ;
}
int nLen = ::WideCharToMultiByte (CP_UTF8, 0, buf, -1, NULL, 0, NULL, NULL);
pOutBuf = new char[nLen+1] ;
ZeroMemory (pOutBuf, nLen + 1) ;
::WideCharToMultiByte (CP_UTF8, 0, buf, -1, pOutBuf, nLen, NULL, NULL);
return true;
}
#3
可以使用iconv开源库,支持非常多的语言及字符集
#4
CString str_utf=CString(szU8);
这个不是类型转换吗?他错在哪里呢?
这个不是类型转换吗?他错在哪里呢?
#5
主要是,我现在传入的是一个cstring的字符串,要求我传出的也是一个字符串
#6
已经将第四个参数修改为-1但是还是会遇到同样的问题。
#7
int WideCharToMultiByte(
UINT CodePage, //指定执行转换的代码页
DWORD dwFlags, //允许你进行额外的控制,它会影响使用了读音符号(比如重音)的字符
LPCWSTR lpWideCharStr, //指定要转换为宽字节字符串的缓冲区
int cchWideChar, //指定由参数lpWideCharStr指向的缓冲区的字符个数
LPSTR lpMultiByteStr, //指向接收被转换字符串的缓冲区
int cchMultiByte, //指定由参数lpMultiByteStr指向的缓冲区最大值
LPCSTR lpDefaultChar, //遇到一个不能转换的宽字符,函数便会使用pDefaultChar参数指向的字符
LPBOOL pfUsedDefaultChar //至少有一个字符不能转换为其多字节形式,函数就会把这个变量设为TRUE
);
UINT CodePage, //指定执行转换的代码页
DWORD dwFlags, //允许你进行额外的控制,它会影响使用了读音符号(比如重音)的字符
LPCWSTR lpWideCharStr, //指定要转换为宽字节字符串的缓冲区
int cchWideChar, //指定由参数lpWideCharStr指向的缓冲区的字符个数
LPSTR lpMultiByteStr, //指向接收被转换字符串的缓冲区
int cchMultiByte, //指定由参数lpMultiByteStr指向的缓冲区最大值
LPCSTR lpDefaultChar, //遇到一个不能转换的宽字符,函数便会使用pDefaultChar参数指向的字符
LPBOOL pfUsedDefaultChar //至少有一个字符不能转换为其多字节形式,函数就会把这个变量设为TRUE
);
#8
这个函数仔细看过
UINT CodePage, //指定执行转换的代码页 // unicode转为utf-8 所以使用CP_UTF8
DWORD dwFlags, //允许你进行额外的控制,它会影响使用了读音符号(比如重音)的字符 //不进行额外的处理,所以为null
LPCWSTR lpWideCharStr, //指定要转换为宽字节字符串的缓冲区 //str是我要转换的字符串
int cchWideChar, //指定由参数lpWideCharStr指向的缓冲区的字符个数 //unicode编码时,str.getlength()函数的返回值为字符数
LPSTR lpMultiByteStr, //指向接收被转换字符串的缓冲区 //第一次调用为null 第二次为szU8
int cchMultiByte, //指定由参数lpMultiByteStr指向的缓冲区最大值 //第一次调用为0 第二次为u8Len
LPCSTR lpDefaultChar, //遇到一个不能转换的宽字符,函数便会使用pDefaultChar参数指向的字符 //NULL,默认的指向字符是?
LPBOOL pfUsedDefaultChar //至少有一个字符不能转换为其多字节形式,函数就会把这个变量设为TRUE //将这个变量设为TRUE,变异出错,因为他要求的是一个int 不是LPBOOL型
UINT CodePage, //指定执行转换的代码页 // unicode转为utf-8 所以使用CP_UTF8
DWORD dwFlags, //允许你进行额外的控制,它会影响使用了读音符号(比如重音)的字符 //不进行额外的处理,所以为null
LPCWSTR lpWideCharStr, //指定要转换为宽字节字符串的缓冲区 //str是我要转换的字符串
int cchWideChar, //指定由参数lpWideCharStr指向的缓冲区的字符个数 //unicode编码时,str.getlength()函数的返回值为字符数
LPSTR lpMultiByteStr, //指向接收被转换字符串的缓冲区 //第一次调用为null 第二次为szU8
int cchMultiByte, //指定由参数lpMultiByteStr指向的缓冲区最大值 //第一次调用为0 第二次为u8Len
LPCSTR lpDefaultChar, //遇到一个不能转换的宽字符,函数便会使用pDefaultChar参数指向的字符 //NULL,默认的指向字符是?
LPBOOL pfUsedDefaultChar //至少有一个字符不能转换为其多字节形式,函数就会把这个变量设为TRUE //将这个变量设为TRUE,变异出错,因为他要求的是一个int 不是LPBOOL型
#9
你应该先把CString转换成Unicode,再转换成UTF-8
再默认的VC编译参数下,CString本身是MBCS的不是Unicode。所以计算长度会出错。
任何编码的字符串,转换到UTF-8,都要先to unicode,在utf-8
再默认的VC编译参数下,CString本身是MBCS的不是Unicode。所以计算长度会出错。
任何编码的字符串,转换到UTF-8,都要先to unicode,在utf-8
#10
入参传递引用过去,也是出参,供参考
void ConvertANSIToUTF8(CString &strANSI)
{
// CString to Unicode
int nLen = ::MultiByteToWideChar(CP_ACP,MB_ERR_INVALID_CHARS,(LPCTSTR)strANSI,-1,NULL,0);
unsigned short * wszUTF_8 = new unsigned short[nLen+1];
memset(wszUTF_8, 0, nLen * 2 + 2);
nLen = MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strANSI, -1, wszUTF_8, nLen);
// Unicode to UTF-8
nLen = WideCharToMultiByte(CP_UTF8, 0, wszUTF_8, -1, NULL, 0, NULL, NULL);
char *szUTF8=new char[nLen + 1];
memset(szUTF8, 0, nLen + 1);
WideCharToMultiByte (CP_UTF8, 0, wszUTF_8, -1, szUTF8, nLen, NULL,NULL);
strANSI = szUTF8;
delete wszUTF_8;
delete szUTF8;
}
void ConvertANSIToUTF8(CString &strANSI)
{
// CString to Unicode
int nLen = ::MultiByteToWideChar(CP_ACP,MB_ERR_INVALID_CHARS,(LPCTSTR)strANSI,-1,NULL,0);
unsigned short * wszUTF_8 = new unsigned short[nLen+1];
memset(wszUTF_8, 0, nLen * 2 + 2);
nLen = MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strANSI, -1, wszUTF_8, nLen);
// Unicode to UTF-8
nLen = WideCharToMultiByte(CP_UTF8, 0, wszUTF_8, -1, NULL, 0, NULL, NULL);
char *szUTF8=new char[nLen + 1];
memset(szUTF8, 0, nLen + 1);
WideCharToMultiByte (CP_UTF8, 0, wszUTF_8, -1, szUTF8, nLen, NULL,NULL);
strANSI = szUTF8;
delete wszUTF_8;
delete szUTF8;
}
#1
CString str_utf=CString(szU8);
这句是错误的。
这句是错误的。
#2
涉及到utf-8和unicode最好就别用CString了,不明了
下面的函数出去后记得使用delete []释放pOutBuf。
bool UnicodeToUtf8(const wchar_t* buf, char * & pOutBuf)
{
if (buf == NULL)
{
return NULL ;
}
int nLen = ::WideCharToMultiByte (CP_UTF8, 0, buf, -1, NULL, 0, NULL, NULL);
pOutBuf = new char[nLen+1] ;
ZeroMemory (pOutBuf, nLen + 1) ;
::WideCharToMultiByte (CP_UTF8, 0, buf, -1, pOutBuf, nLen, NULL, NULL);
return true;
}
下面的函数出去后记得使用delete []释放pOutBuf。
bool UnicodeToUtf8(const wchar_t* buf, char * & pOutBuf)
{
if (buf == NULL)
{
return NULL ;
}
int nLen = ::WideCharToMultiByte (CP_UTF8, 0, buf, -1, NULL, 0, NULL, NULL);
pOutBuf = new char[nLen+1] ;
ZeroMemory (pOutBuf, nLen + 1) ;
::WideCharToMultiByte (CP_UTF8, 0, buf, -1, pOutBuf, nLen, NULL, NULL);
return true;
}
#3
可以使用iconv开源库,支持非常多的语言及字符集
#4
CString str_utf=CString(szU8);
这个不是类型转换吗?他错在哪里呢?
这个不是类型转换吗?他错在哪里呢?
#5
主要是,我现在传入的是一个cstring的字符串,要求我传出的也是一个字符串
#6
已经将第四个参数修改为-1但是还是会遇到同样的问题。
#7
int WideCharToMultiByte(
UINT CodePage, //指定执行转换的代码页
DWORD dwFlags, //允许你进行额外的控制,它会影响使用了读音符号(比如重音)的字符
LPCWSTR lpWideCharStr, //指定要转换为宽字节字符串的缓冲区
int cchWideChar, //指定由参数lpWideCharStr指向的缓冲区的字符个数
LPSTR lpMultiByteStr, //指向接收被转换字符串的缓冲区
int cchMultiByte, //指定由参数lpMultiByteStr指向的缓冲区最大值
LPCSTR lpDefaultChar, //遇到一个不能转换的宽字符,函数便会使用pDefaultChar参数指向的字符
LPBOOL pfUsedDefaultChar //至少有一个字符不能转换为其多字节形式,函数就会把这个变量设为TRUE
);
UINT CodePage, //指定执行转换的代码页
DWORD dwFlags, //允许你进行额外的控制,它会影响使用了读音符号(比如重音)的字符
LPCWSTR lpWideCharStr, //指定要转换为宽字节字符串的缓冲区
int cchWideChar, //指定由参数lpWideCharStr指向的缓冲区的字符个数
LPSTR lpMultiByteStr, //指向接收被转换字符串的缓冲区
int cchMultiByte, //指定由参数lpMultiByteStr指向的缓冲区最大值
LPCSTR lpDefaultChar, //遇到一个不能转换的宽字符,函数便会使用pDefaultChar参数指向的字符
LPBOOL pfUsedDefaultChar //至少有一个字符不能转换为其多字节形式,函数就会把这个变量设为TRUE
);
#8
这个函数仔细看过
UINT CodePage, //指定执行转换的代码页 // unicode转为utf-8 所以使用CP_UTF8
DWORD dwFlags, //允许你进行额外的控制,它会影响使用了读音符号(比如重音)的字符 //不进行额外的处理,所以为null
LPCWSTR lpWideCharStr, //指定要转换为宽字节字符串的缓冲区 //str是我要转换的字符串
int cchWideChar, //指定由参数lpWideCharStr指向的缓冲区的字符个数 //unicode编码时,str.getlength()函数的返回值为字符数
LPSTR lpMultiByteStr, //指向接收被转换字符串的缓冲区 //第一次调用为null 第二次为szU8
int cchMultiByte, //指定由参数lpMultiByteStr指向的缓冲区最大值 //第一次调用为0 第二次为u8Len
LPCSTR lpDefaultChar, //遇到一个不能转换的宽字符,函数便会使用pDefaultChar参数指向的字符 //NULL,默认的指向字符是?
LPBOOL pfUsedDefaultChar //至少有一个字符不能转换为其多字节形式,函数就会把这个变量设为TRUE //将这个变量设为TRUE,变异出错,因为他要求的是一个int 不是LPBOOL型
UINT CodePage, //指定执行转换的代码页 // unicode转为utf-8 所以使用CP_UTF8
DWORD dwFlags, //允许你进行额外的控制,它会影响使用了读音符号(比如重音)的字符 //不进行额外的处理,所以为null
LPCWSTR lpWideCharStr, //指定要转换为宽字节字符串的缓冲区 //str是我要转换的字符串
int cchWideChar, //指定由参数lpWideCharStr指向的缓冲区的字符个数 //unicode编码时,str.getlength()函数的返回值为字符数
LPSTR lpMultiByteStr, //指向接收被转换字符串的缓冲区 //第一次调用为null 第二次为szU8
int cchMultiByte, //指定由参数lpMultiByteStr指向的缓冲区最大值 //第一次调用为0 第二次为u8Len
LPCSTR lpDefaultChar, //遇到一个不能转换的宽字符,函数便会使用pDefaultChar参数指向的字符 //NULL,默认的指向字符是?
LPBOOL pfUsedDefaultChar //至少有一个字符不能转换为其多字节形式,函数就会把这个变量设为TRUE //将这个变量设为TRUE,变异出错,因为他要求的是一个int 不是LPBOOL型
#9
你应该先把CString转换成Unicode,再转换成UTF-8
再默认的VC编译参数下,CString本身是MBCS的不是Unicode。所以计算长度会出错。
任何编码的字符串,转换到UTF-8,都要先to unicode,在utf-8
再默认的VC编译参数下,CString本身是MBCS的不是Unicode。所以计算长度会出错。
任何编码的字符串,转换到UTF-8,都要先to unicode,在utf-8
#10
入参传递引用过去,也是出参,供参考
void ConvertANSIToUTF8(CString &strANSI)
{
// CString to Unicode
int nLen = ::MultiByteToWideChar(CP_ACP,MB_ERR_INVALID_CHARS,(LPCTSTR)strANSI,-1,NULL,0);
unsigned short * wszUTF_8 = new unsigned short[nLen+1];
memset(wszUTF_8, 0, nLen * 2 + 2);
nLen = MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strANSI, -1, wszUTF_8, nLen);
// Unicode to UTF-8
nLen = WideCharToMultiByte(CP_UTF8, 0, wszUTF_8, -1, NULL, 0, NULL, NULL);
char *szUTF8=new char[nLen + 1];
memset(szUTF8, 0, nLen + 1);
WideCharToMultiByte (CP_UTF8, 0, wszUTF_8, -1, szUTF8, nLen, NULL,NULL);
strANSI = szUTF8;
delete wszUTF_8;
delete szUTF8;
}
void ConvertANSIToUTF8(CString &strANSI)
{
// CString to Unicode
int nLen = ::MultiByteToWideChar(CP_ACP,MB_ERR_INVALID_CHARS,(LPCTSTR)strANSI,-1,NULL,0);
unsigned short * wszUTF_8 = new unsigned short[nLen+1];
memset(wszUTF_8, 0, nLen * 2 + 2);
nLen = MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strANSI, -1, wszUTF_8, nLen);
// Unicode to UTF-8
nLen = WideCharToMultiByte(CP_UTF8, 0, wszUTF_8, -1, NULL, 0, NULL, NULL);
char *szUTF8=new char[nLen + 1];
memset(szUTF8, 0, nLen + 1);
WideCharToMultiByte (CP_UTF8, 0, wszUTF_8, -1, szUTF8, nLen, NULL,NULL);
strANSI = szUTF8;
delete wszUTF_8;
delete szUTF8;
}