vs开发windows程序中文乱码

读取文件的文件编码格式和vs的字符集设置很重要,读取到程序里的中文字符串需要做转换处理

1、vs字符集是unicode一般需要做如下处理

如果文件编码是gbk编码

void gb2312ToUnicode(const string& src, wstring& result)
{
	int n = MultiByteToWideChar(CP_ACP, 0, src.c_str(), -1, NULL, 0);
	result.resize(n);
	::MultiByteToWideChar(CP_ACP, 0, src.c_str(), -1, (LPWSTR)result.c_str(), result.length());
}

如果文件编码是utf8编码

void utf8ToUnicode(const string& src, wstring& result)
{
	int n = MultiByteToWideChar(CP_UTF8, 0, src.c_str(), -1, NULL, 0);
	result.resize(n);
	::MultiByteToWideChar(CP_UTF8, 0, src.c_str(), -1, (LPWSTR)result.c_str(), result.length());
}

2、vs字符集是多字符集一般需要做如下处理

如果文件编码是gbk或者ansi,则不需要处理

如果文件编码是utf8,需要utf8ToUnicode

其它相关类型转换

void unicodeToUTF8(const wstring &src, string& result)
{
	int n = WideCharToMultiByte(CP_UTF8, 0, src.c_str(), -1, 0, 0, 0, 0);
	result.resize(n);
	::WideCharToMultiByte(CP_UTF8, 0, src.c_str(), -1, (char*)result.c_str(), result.length(), 0, 0);
}
void unicodeToGB2312(const wstring& wstr, string& result)
{
	int n = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, 0, 0, 0, 0);
	result.resize(n);
	::WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, (char*)result.c_str(), n, 0, 0);
}
void utf8ToUnicode(const string& src, wstring& result)
{
	int n = MultiByteToWideChar(CP_UTF8, 0, src.c_str(), -1, NULL, 0);
	result.resize(n);
	::MultiByteToWideChar(CP_UTF8, 0, src.c_str(), -1, (LPWSTR)result.c_str(), result.length());
}

void gb2312ToUnicode(const string& src, wstring& result)
{
	int n = MultiByteToWideChar(CP_ACP, 0, src.c_str(), -1, NULL, 0);
	result.resize(n);
	::MultiByteToWideChar(CP_ACP, 0, src.c_str(), -1, (LPWSTR)result.c_str(), result.length());
}
string WCharToMByte(LPCWSTR lpcwszStr)
{
	string str;
	DWORD dwMinSize = 0;
	LPSTR lpszStr = NULL;
	dwMinSize = WideCharToMultiByte(CP_OEMCP, NULL, lpcwszStr, -1, NULL, 0, NULL, FALSE);
	if (0 == dwMinSize)
	{
		return FALSE;
	}
	lpszStr = new char[dwMinSize];
	WideCharToMultiByte(CP_OEMCP, NULL, lpcwszStr, -1, lpszStr, dwMinSize, NULL, FALSE);
	str = lpszStr;
	delete[] lpszStr;
	return str;
}
void Wchar_tToString(std::string& szDst, wchar_t *wchar)
{
	wchar_t * wText = wchar;
	DWORD dwNum = WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, NULL, 0, NULL, FALSE);// WideCharToMultiByte的运用
	char *psText; // psText为char*的临时数组,作为赋值给std::string的中间变量
	psText = new char[dwNum];
	WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, psText, dwNum, NULL, FALSE);// WideCharToMultiByte的再次运用
	szDst = psText;// std::string赋值
	delete[]psText;// psText的清除
}

其它

1、vs中常量字符串中文是否为乱码只与文件编码有关

gbk可以正常显示中文,utf8-bom可以正常显示中文,utf8无bom中文显示乱码,需要转为unicode字符;

2、vs中属性里设置的字符集关乎windows系统调用的API是调用宽字符API还是多字节API;例如

#ifdef UNICODE
    return GetPrivateProfileStringW(
#else
    return GetPrivateProfileStringA(
#endif

3、utf8-bom无乱码问题是因为bom头可以被识别为utf8-bom编码格式,utf8出现乱码是因为系统无法识别编码格式默认使用操作系统的本地编码设置,在简体中文的操作系统上一般使用的是unicode编码;

有关vs工程使用utf8编码的方法可以参考vs2015:/utf-8选项解决UTF-8 without BOM 源码中文输出乱码问题_10km的专栏-CSDN博客

你可能感兴趣的:(windows)