Windows编程下的字符串格式及编码问题
Posted CodeBowl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Windows编程下的字符串格式及编码问题相关的知识,希望对你有一定的参考价值。
大家在学习或者使用Windows编程中,经常会碰到字符串之间的转换,char*转LPCWSTR也是其中一个比较常见的转换。下面就列出几种比较常用的转换方法。大家可以根据自己的需求选择相对应的方法,下面来一起学习学习吧。
为什么总结这个问题
一些代码在其他平台下是正常的,但是在Windows环境下,经常遇到中文乱码的情况,很是头疼!
1、通过MultiByteToWideChar函数转换
MultiByteToWideChar函数是将多字节转换为宽字节的一个API函数,它的原型如下:
int MultiByteToWideChar(
UINT CodePage, // code page
DWORD dwFlags, // character-type options
LPCSTR lpMultiByteStr, // string to map
int cbMultiByte, // number of bytes in string
LPWSTR lpWideCharStr, // wide-character buffer
int cchWideChar // size of buffer
);
LPCWSTR实际上也是CONST WCHAR *类型
char* szStr = "测试字符串";
WCHAR wszClassName[256];
memset(wszClassName,0,sizeof(wszClassName));
MultiByteToWideChar(CP_ACP,0,szStr,strlen(szStr)+1,wszClassName,
sizeof(wszClassName)/sizeof(wszClassName[0]));
2、通过T2W转换宏
char* szStr = "测试字符串";
CString str = CString(szStr);
USES_CONVERSION;
LPCWSTR wszClassName = new WCHAR[str.GetLength()+1];
wcscpy((LPTSTR)wszClassName,T2W((LPTSTR)str.GetBuffer(NULL)));
str.ReleaseBuffer();
3、通过A2CW转换
char* szStr = "测试字符串";
CString str = CString(szStr);
USES_CONVERSION;
LPCWSTR wszClassName = A2CW(W2A(str));
str.ReleaseBuffer();
上述方法都是UniCode环境下测试的。
4.编码格式转换:ANSI,UTF-8,UNICODE字符在Windows下的转换
//convert_code.hpp
//调用后不要忘记delete[]掉
#pragma once
#include <windows.h>
static const wchar_t* ConvertUtf8ToUnicode(const char* _ansiUtf8)
{
if (_ansiUtf8 == NULL)
{
return L"";
}
int len = MultiByteToWideChar(CP_UTF8, 0, _ansiUtf8, -1, NULL, 0);
wchar_t* wszUnicode = new wchar_t[(size_t)len + 1];
memset(wszUnicode, 0, ((size_t)len + 1) * sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0, _ansiUtf8, -1, wszUnicode, len);
return wszUnicode;
}
static const char* ConvertUnicodeToUtf8(const wchar_t* _szUnicode)
{
if (_szUnicode == NULL)
{
return "";
}
int len = WideCharToMultiByte(CP_UTF8, 0, _szUnicode, -1, NULL, 0, NULL, NULL);
char* szUtf8 = new char[(size_t)len + 1];
memset(szUtf8, 0, ((size_t)len + 1) * sizeof(char));
WideCharToMultiByte(CP_UTF8, 0, _szUnicode, -1, szUtf8, len, NULL, NULL);
return szUtf8;
}
static const wchar_t* ConvertAnsiToUnicode(const char* _szAnsi)
{
if (_szAnsi == NULL)
{
return L"";
}
int len = MultiByteToWideChar(CP_ACP, 0, _szAnsi, -1, NULL, 0);
wchar_t* wszUnicode = new wchar_t[(size_t)len + 1];
memset(wszUnicode, 0, ((size_t)len + 1) * sizeof(wchar_t));
MultiByteToWideChar(CP_ACP, 0, _szAnsi, -1, wszUnicode, len);
return wszUnicode;
}
static const char* ConvertUnicodeToAnsi(const wchar_t* _szUnicode)
{
if (_szUnicode == NULL)
{
return "";
}
int len = WideCharToMultiByte(CP_ACP, 0, _szUnicode, -1, NULL, 0, NULL, NULL);
char* szAnsi = new char[(size_t)len + 1];
memset(szAnsi, 0, ((size_t)len + 1) * sizeof(char));
WideCharToMultiByte(CP_ACP, 0, _szUnicode, -1, szAnsi, len, NULL, NULL);
return szAnsi;
}
static const char* ConvertAnsiToUtf8(const char* _szAnsi)
{
if (NULL == _szAnsi)
{
return "";
}
int dwAnsiLen = MultiByteToWideChar(CP_ACP, NULL, _szAnsi, -1, NULL, NULL);
wchar_t* szTmpUnicode = new wchar_t[(size_t)dwAnsiLen + 1];
memset(szTmpUnicode, 0, sizeof(wchar_t) * ((size_t)dwAnsiLen + 1));
MultiByteToWideChar(CP_ACP, NULL, _szAnsi, -1, szTmpUnicode, dwAnsiLen);
int dwUtf8Len = WideCharToMultiByte(CP_UTF8, 0, szTmpUnicode, -1, NULL, 0, NULL, NULL);
char* szUtf8 = new char[(size_t)dwUtf8Len + 1];
memset(szUtf8, 0, sizeof(char) * ((size_t)dwUtf8Len + 1));
WideCharToMultiByte(CP_UTF8, 0, szTmpUnicode, -1, szUtf8, dwUtf8Len, NULL, NULL);
delete[] szTmpUnicode;
return szUtf8;
}
static const char* ConvertUtf8ToAnsi(const char* _szUtf8)
{
if (NULL == _szUtf8)
{
return "";
}
int dwAnsiLen = MultiByteToWideChar(CP_UTF8, NULL, _szUtf8, -1, NULL, NULL);
wchar_t* szTmpUnicode = new wchar_t[(size_t)dwAnsiLen + 1];
memset(szTmpUnicode, 0, sizeof(wchar_t) * ((size_t)dwAnsiLen + 1));
MultiByteToWideChar(CP_UTF8, NULL, _szUtf8, -1, szTmpUnicode, dwAnsiLen);
int dwUtf8Len = WideCharToMultiByte(CP_ACP, 0, szTmpUnicode, -1, NULL, 0, NULL, NULL);
char* szAnsi = new char[(size_t)dwUtf8Len + 1];
memset(szAnsi, 0, sizeof(char) * ((size_t)dwUtf8Len + 1));
WideCharToMultiByte(CP_ACP, 0, szTmpUnicode, -1, szAnsi, dwUtf8Len, NULL, NULL);
delete[] szTmpUnicode;
return szAnsi;
}
5. utf-8和GBK转换
除了一些旧的、没有考虑到兼容性的网页还在用gbk做编码外,大部分的网页都已经用utf-8做编码了。但是最令人头疼的是,windows的控制台是很不好显示utf-8的。
#include <string>
#include <windows.h>
using std::string;
//gbk 转 utf8
string GBKToUTF8(const string& strGBK)
{
string strOutUTF8 = "";
WCHAR * str1;
int n = MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, NULL, 0);
str1 = new WCHAR[n];
MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, str1, n);
n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);
char * str2 = new char[n];
WideCharToMultiByte(CP_UTF8, 0, str1, -1, str2, n, NULL, NULL);
strOutUTF8 = str2;
delete[]str1;
str1 = NULL;
delete[]str2;
str2 = NULL;
return strOutUTF8;
}
//utf-8 转 gbk
string UTF8ToGBK(const string& strUTF8)
{
int len = MultiByteToWideChar(CP_UTF8, 0, strUTF8.c_str(), -1, NULL, 0);
unsigned short * wszGBK = new unsigned short[len + 1];
memset(wszGBK, 0, len * 2 + 2);
MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUTF8.c_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);
//strUTF8 = szGBK;
std::string strTemp(szGBK);
delete[]szGBK;
delete[]wszGBK;
return strTemp;
}
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
参考资料
http://www.cppblog.com/Shihira/archive/2013/10/28/200124.aspx
以上是关于Windows编程下的字符串格式及编码问题的主要内容,如果未能解决你的问题,请参考以下文章