• 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;
    }
  • 相关阅读:
    EXE中释放文件
    关闭GS选项,解决注入后崩溃
    HDU2516 取石子游戏
    HDU2188 选拔志愿者
    HDU2149 Public Sale
    HDU2147 kiki's game
    HDU1846 Brave Game
    LightOJ1214 Large Division
    POJ2480 Longge's problem
    HDU 5880 Family View
  • 原文地址:https://www.cnblogs.com/carl2380/p/2043359.html
Copyright © 2020-2023  润新知