MFC中CStdioFile处理文本文件乱码的

参考 

MFC中CStdioFile处理文本文件乱码的原因及解决方法(编程 Unicode 环境下读写 ANSI 文件)http://hi.baidu.com/jfc_09/blog/item/f4d7fdd72685a8cf50da4b79.html

VC 编程ANSI环境下读写Unicode文件

http://blog.csdn.net/sunboy_2050/archive/2009/12/17/5019900.aspx-->

 CStdioFile在UNICODE环境下读取文本行〔转〕 - 乖小猫的日志 - 网易博

!!!http://blog.163.com/neverforget_yang/blog/static/13095275720104482459666/

BOOL CLanguageManager::ParseResourceFile(LPCTSTR lpszFilePath, LPCTSTR lpszHeaderFilePath)
{..	//	resource file
		CStdioFile Resfile;
		if (Resfile.Open(lpszFilePath, CFile::modeRead))
		{
			int index =0;
			CString src;
			CString strHeaderRow;
			while (Resfile.ReadString(strHeaderRow))
			{
				!!!Ansi2Unicode(strHeaderRow);
				src = src + _T("\r\n");
				src = src + strHeaderRow;
			}		  
// 将Unicode字符转换为Char型字符
#define BUFFER_SIZE_KILO 0
int UnicodeToChar(CString &strIn, char *pchOut, int nCharLen)
{
	if(pchOut == NULL)
	{
		return 0;
	}
	int nLen = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)strIn.GetBuffer(BUFFER_SIZE_KILO),-1, NULL, 0, NULL, NULL);
	nLen = min(nLen, nCharLen);
	WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)strIn.GetBuffer(BUFFER_SIZE_KILO), -1, pchOut,
		nLen, NULL, NULL);

	if(nLen < nCharLen)
	{
		pchOut[nLen] = 0;
	}
	return nLen;
} 

void Ansi2Unicode(CString &str)
{
	//注:此函数在编译的时候会提示
	//	warning C4244: '=' : conversion from 'unsigned short' to 'char', possible loss of data
	//	不用管它,丢失的数据是我们不需要的。
	char *szBuf = new char[str.GetLength()];
	for (int i = 0 ; i < str.GetLength(); i++)
	{
		szBuf[i] = str.GetAt(i);
	}
	CharToUnicode(szBuf , &str);
	delete []szBuf;
    CStdioFile Resfile;
    if (Resfile.Open(lpszFilePath, CFile::modeRead))
    {
        int index =0;
        CString src;
        CString str_Unicode,str_MSBC;
        while (Resfile.ReadString(str_MSBC))
        {
            //    注意:采用这种方式处理的文件必须为ANSI编码,不能使UNICODE
            // 把“_MSBC环境”下的“CString”(CHAR),直接填充到了“Unicode环境”下的“CString”(WCHAR)中,
            // 这样会导致“汉字”显示成乱码。如果想正确显示,需要对该字符串进行相应的处理。
            if(str_MSBC != _T(""))
            {
                // 将保存成“宽字节类型”的“单字节类型”字符串(Unicode环境),
                // 还原为正确的“单字节类型”字符串(_MSBC环境)。
                _UnicodeOf_MSBCTo_MSBC(&str_MSBC);
                // 将“单字节的字串符类型(_MSBC环境)”转换为“宽字节的字符串类型(Unicode环境)”
                _MSBCTo_Unicode(str_MSBC, &str_Unicode);
View Code

}

上述处理有问题,后来又参照 http://hi.baidu.com/coderui/item/a9a634439e25ca15896d108d

进行处理

    CStdioFile Resfile;
    if (Resfile.Open(lpszFilePath, CFile::modeRead))
    {
        int index =0;
        CString src;
        CString str_Unicode,str_MSBC;
        while (Resfile.ReadString(str_MSBC))
        {
            //    注意:采用这种方式处理的文件必须为ANSI编码,不能使UNICODE
            // 把“_MSBC环境”下的“CString”(CHAR),直接填充到了“Unicode环境”下的“CString”(WCHAR)中,
            // 这样会导致“汉字”显示成乱码。如果想正确显示,需要对该字符串进行相应的处理。
            if(str_MSBC != _T(""))
            {
                // 将保存成“宽字节类型”的“单字节类型”字符串(Unicode环境),
                // 还原为正确的“单字节类型”字符串(_MSBC环境)。
                _UnicodeOf_MSBCTo_MSBC(&str_MSBC);
                // 将“单字节的字串符类型(_MSBC环境)”转换为“宽字节的字符串类型(Unicode环境)”
                _MSBCTo_Unicode(str_MSBC, &str_Unicode);
//
// 将“单字节的字串符类型(_MSBC环境)”转换为“宽字节的字符串类型(Unicode环境)”
//
INT _MSBCTo_Unicode(CString strInPut_MSBC, CString *strOutPut_Unicode)
{
INT nLen;
CHAR *pcBuf;
if(strInPut_MSBC == _T(""))
{
   return 0;
}
pcBuf = (CHAR *)strInPut_MSBC.GetBuffer(strInPut_MSBC.GetLength());
nLen = MultiByteToWideChar(CP_ACP, 0, pcBuf, -1, NULL, 0);
// (Unicode环境WCHAR需要加1,默认已经加1了)
WCHAR *pwBuf = new WCHAR[nLen];
memset(pwBuf, 0, nLen);
MultiByteToWideChar(CP_ACP, 0, pcBuf, -1, pwBuf, nLen);
strOutPut_Unicode->Format(_T("%s"), pwBuf);
delete []pwBuf;
nLen -= 1;
return nLen;
}
//
// 将“宽字节的字符串类型(Unicode环境)”转换为“单字节的字串符类型(_MSBC环境)”
//
INT _UnicodeTo_MSBC(CString strInPut_Unicode, CString *strOutPut_MSBC)
{
INT nLen;
WCHAR *pwBuf;
if(strInPut_Unicode == _T(""))
{
   return 0;
}
pwBuf = strInPut_Unicode.GetBuffer(strInPut_Unicode.GetLength());
nLen = WideCharToMultiByte(CP_ACP, 0, pwBuf, -1, NULL, 0, NULL, NULL);
// (Unicode环境需要加2,不然Format时内存数据格式不对程序会崩)
CHAR *pcBuf = new CHAR[nLen + 2];
memset(pcBuf, 0, nLen + 2);
WideCharToMultiByte(CP_ACP, 0, pwBuf, -1, pcBuf, nLen, NULL, NULL);
strOutPut_MSBC->Format(_T("%s"), pcBuf);
delete []pcBuf;
nLen -= 1;
return nLen;
}
//
// 将保存成“宽字节类型”的“单字节类型”字符串(Unicode环境),
// 还原为正确的“单字节类型”字符串(_MSBC环境)。
//
VOID _UnicodeOf_MSBCTo_MSBC(CString *str)
{
INT nLen;
CHAR *pcBuf;
nLen = str->GetLength();
// (Unicode环境需要加3,不然Format时内存数据格式不对程序会崩)
pcBuf = new CHAR[nLen + 3];
memset(pcBuf, 0, nLen + 3);
for (INT i = 0 ; i < nLen; i++)
{
   pcBuf[i] = (CHAR)str->GetAt(i);
}
str->Format(_T("%s"), pcBuf);
delete []pcBuf;
}
原文地址:https://www.cnblogs.com/carl2380/p/2043359.html