【编程笔记】UNICODE和UTF-8和ASCII互转

最近维护一个项目时发现,MFC的Cstring类型写到ini文本时,出现了乱码。因为写入的数据带有类似的特殊字符❀,由于ini默认创建的编码格式为GBK编码格式,但是这个特殊字符在默认的GBK编码下是不能识别的,会以?的形式存在。那这个特殊字符的编码是什么,暂时还没搞清楚。但是既然知道存在这样的bug,那么我们就有了相应的解决方法:在写入ini文件时,先将unicode编码的内容转成utf-8(utf-8具有世界通用性,所以显示这个特殊字符不在话下)再写入到ini文件,显然在GBK编码的ini文件中显示UTF-8编码的内容肯定是乱码,比如中文或者特殊字符。当我们要取出写入ini文件的内容时,我们又需要进行一次转码,将UTF-8转成UNICODE编码。

源码如下:

//UTF8转Unicode
std::wstring UTF8ToUnicode(const char* v_szUTF8)
{
	std::wstring wstrUnicode;
	if(NULL == v_szUTF8)
	{
		return wstrUnicode;
	}
	DWORD dwNum = MultiByteToWideChar(CP_UTF8, 0, v_szUTF8, -1, NULL, 0);
	if(ERROR_NO_UNICODE_TRANSLATION == dwNum)
	{
		return wstrUnicode;
	}
	if(0 == dwNum)
	{
		return wstrUnicode;
	}
	WCHAR* wcsUnicode = new WCHAR[dwNum + 1];
	memset(wcsUnicode, 0, (dwNum + 1) * sizeof(WCHAR));

	MultiByteToWideChar(CP_UTF8, 0, v_szUTF8, -1, wcsUnicode ,dwNum);
	wstrUnicode = wcsUnicode;
	if(NULL != wcsUnicode)
	{
		delete [] wcsUnicode;
	}
	return wstrUnicode;
}
//Unicode转UTF8
std::string UnicodeToUTF8(const WCHAR* v_wcsUnicode)
{
	std::string strUTF8;
	if(NULL == v_wcsUnicode)
	{
		return strUTF8;
	}
	DWORD dwNum = WideCharToMultiByte(CP_UTF8, 0, v_wcsUnicode, -1, NULL, 0, NULL, 0);
	if(0 == dwNum)
	{
		return strUTF8;
	}
	char* szUTF8 = new char[dwNum + 1];
	memset(szUTF8, 0, (dwNum + 1) * sizeof(char));

	//将宽字节字符串转换为多字节字符串
	WideCharToMultiByte(CP_UTF8, 0, v_wcsUnicode, -1, szUTF8, dwNum, NULL, 0);
	strUTF8 = szUTF8;
	if(NULL != szUTF8)
	{
		delete [] szUTF8;
	}
	return strUTF8;
}
//Unicode转ASCII
std::string UnicodeToASCII(const WCHAR* v_wcsUnicode)
{
	std::string strASCII;
	if(NULL == v_wcsUnicode)
	{
		return strASCII;
	}
	DWORD dwNum = WideCharToMultiByte(CP_OEMCP, 0, v_wcsUnicode, -1, NULL, 0, NULL, 0);
	if(0 == dwNum)
	{
		return strASCII;
	}
	char* szASCII = new char[dwNum + 1];
	memset(szASCII, 0, (dwNum + 1) * sizeof(char));

	//将宽字节字符串转换为多字节字符串
	WideCharToMultiByte(CP_OEMCP, 0, v_wcsUnicode, -1, szASCII, dwNum, NULL, 0);
	strASCII = szASCII;
	if(NULL != szASCII)
	{
		delete [] szASCII;
	}
	return strASCII;
}

 

//ASCII转Unicode
std::wstring ASCIIToUnicode(const char* v_szASCII)
{
	std::wstring wstrUnicode;
	if(NULL == v_szASCII)
	{
		return wstrUnicode;
	}
	DWORD dwNum = MultiByteToWideChar(CP_ACP, 0, v_szASCII, -1, NULL, 0);
	if(ERROR_NO_UNICODE_TRANSLATION == dwNum)
	{
		return wstrUnicode;
	}
	if(0 == dwNum)
	{
		return wstrUnicode;
	}
	WCHAR* wcsUnicode = new WCHAR[dwNum + 1];
	memset(wcsUnicode, 0, (dwNum + 1) * sizeof(WCHAR));

	MultiByteToWideChar(CP_ACP, 0, v_szASCII, -1, wcsUnicode ,dwNum);
	wstrUnicode = wcsUnicode;
	if(NULL != wcsUnicode)
	{
		delete [] wcsUnicode;
	}
	return wstrUnicode;
}

 

//UTF8转ASCII
std::string UTF8ToASCII(const char* v_szUTF8)
{
	std::string strASCII;
	if(NULL == v_szUTF8)
	{
		return strASCII;
	}
	//先把 utf8 转为 unicode
	std::wstring wstrUnicode = UTF8ToUnicode(v_szUTF8);
	//最后把 unicode 转为 ascii
	strASCII = UnicodeToASCII(wstrUnicode.c_str());
	return strASCII;
}

 

//ASCII转UTF8
std::string ASCIIToUTF8(const char* v_szASCII)
{
	std::string strUTF8;
	if(NULL == v_szASCII)
	{
		return strUTF8;
	}
	//先把 ascii 转为 unicode
	std::wstring wstrUnicode = ASCIIToUnicode(v_szASCII);
	//最后把 unicode 转为 utf8
	strUTF8 = UnicodeToUTF8(wstrUnicode.c_str());
	return strUTF8;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值