none
如何在UNICODE工程环境下读取ANSI格式TXT? RRS feed

  • 问题

  •     m_file为CFile对象,代码如下:

       m_strFileName=L"Text\\1.txt";
        if (!m_file.Open(m_strFileName,CFile::modeRead | CFile::shareDenyNone))
        {
            PostQuitMessage(NULL);
        }

        int nChars;
        m_strContent=_T("");
        DWORD dwLength = (DWORD)m_file.GetLength();
        char *buf=new char[dwLength];
        m_file.Read(buf,dwLength);
        nChars=MultiByteToWideChar(CP_ACP,0,buf,-1,NULL,0);
        wchar_t *wbuff=new wchar_t [nChars];
        MultiByteToWideChar(CP_ACP,0,buf,-1,wbuff,nChars);
        m_strContent = wbuff;
        AfxMessageBox(m_strContent);

    我用以上的代码能读取到TXT的内容,但是不知为何在字符串的后面一段乱码。如图:

    求各位大侠指教啦!


    • 已编辑 yshkcj 2012年7月26日 4:59
    2012年7月26日 4:00

答案

  • 您好,

    如果您在以下两行设置断点:

    char *buf=new char[dwLength];

    wchar_t *wbuff=new wchar_t [nChars];

    就可以看到bufwbuff的最后面都包含了一些乱码。最终显示的乱码就是从这里产生的。

    这是因为,bufwbuff都是指针,它们不像数组有固定的长度。

    解决方法:

    AfxMessageBox(m_strContent);这一句话前面加上:

    m_strContent[dwLength] = 0;

    这相当于使m_strContent指向的内容变成了带’\0’结束符的字符串。

    此外,其实并不需要用nChar保存buf的长度,直接用dwLength就可以了。m_strContent这个变量也可以省略,直接用wbuff就行了。

    精简后的代码:

    DWORD dwLength = (DWORD)m_file.GetLength();
    char *buf = new char[dwLength];
    m_file.Read(buf,dwLength);
    wchar_t *wbuff = new wchar_t [dwLength];
    MultiByteToWideChar(CP_ACP,0,buf,-1,wbuff,dwLength);
    wbuff[dwLength] = 0;
    AfxMessageBox(wbuff);


    Damon Zheng [MSFT]
    MSDN Community Support | Feedback to us


    2012年8月1日 11:10
    版主
  • try
    	{
    		CFile file(_T("F:\\11.txt"), CFile::modeRead);
    		DWORD dwSize = (DWORD)file.GetLength();
    		char* buf = new char[dwSize + 1];
    		memset(buf, 0, sizeof(char) * (dwSize + 1));
    		file.Read(buf, dwSize);
    		file.Close();
    		AfxMessageBox(CString(buf));
    		delete[] buf;
    		buf = NULL;
    	}
    	catch (CFileException* e)
    	{
    		e->ReportError();
    		e->Delete();
    	}


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    2012年8月1日 13:20
    版主

全部回复

  • 你定个断点,看下 nChars 的大小,按照“文本测试”来看,nChars 应该等于 8。

    你可以这样写:

    LPCTSTR lpText = A2CT(buf);

    2012年7月26日 9:25
  • 您好,

    如果您在以下两行设置断点:

    char *buf=new char[dwLength];

    wchar_t *wbuff=new wchar_t [nChars];

    就可以看到bufwbuff的最后面都包含了一些乱码。最终显示的乱码就是从这里产生的。

    这是因为,bufwbuff都是指针,它们不像数组有固定的长度。

    解决方法:

    AfxMessageBox(m_strContent);这一句话前面加上:

    m_strContent[dwLength] = 0;

    这相当于使m_strContent指向的内容变成了带’\0’结束符的字符串。

    此外,其实并不需要用nChar保存buf的长度,直接用dwLength就可以了。m_strContent这个变量也可以省略,直接用wbuff就行了。

    精简后的代码:

    DWORD dwLength = (DWORD)m_file.GetLength();
    char *buf = new char[dwLength];
    m_file.Read(buf,dwLength);
    wchar_t *wbuff = new wchar_t [dwLength];
    MultiByteToWideChar(CP_ACP,0,buf,-1,wbuff,dwLength);
    wbuff[dwLength] = 0;
    AfxMessageBox(wbuff);


    Damon Zheng [MSFT]
    MSDN Community Support | Feedback to us


    2012年8月1日 11:10
    版主
  • try
    	{
    		CFile file(_T("F:\\11.txt"), CFile::modeRead);
    		DWORD dwSize = (DWORD)file.GetLength();
    		char* buf = new char[dwSize + 1];
    		memset(buf, 0, sizeof(char) * (dwSize + 1));
    		file.Read(buf, dwSize);
    		file.Close();
    		AfxMessageBox(CString(buf));
    		delete[] buf;
    		buf = NULL;
    	}
    	catch (CFileException* e)
    	{
    		e->ReportError();
    		e->Delete();
    	}


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    2012年8月1日 13:20
    版主
  • VisualEleven,

    谢谢分享代码,用CString的确更加方便了:

    CString( const unsigned char* psz );
    throw( CMemoryException );


    Damon Zheng [MSFT]
    MSDN Community Support | Feedback to us

    2012年8月2日 2:45
    版主