锐英源精品开源,禁止转载和任何形式的非法内容使用,违者必究
MFC打开TXT文件并进行编码转换
背景
前几天写了个文章,说明了3个打开TXT文件进行读取内容的方法,哪3个方法里不包括MFC的方式,这个文章介绍MFC的方式。MFC的方式也是要先判断头部标志,再把读取内容转码。
代码
CFile file;
if (file.Open(lpszFilePath, CFile::modeRead, NULL))
{
// Clear old data
if (m_lpszText != NULL)
free(m_lpszText);
// Read data from file
DWORD dwSize = (DWORD)file.GetLength();
LPBYTE lpData = (LPBYTE)malloc(dwSize*sizeof(BYTE));
file.Read(lpData, dwSize);
file.Close();
bResult = TRUE;
// Check for file type
WORD wFlag = 0;
memcpy(&wFlag, lpData, 2);
DWORD dwFlag = 0;
memcpy(&dwFlag, lpData, 3);
int iOffset;
if (wFlag == 0xFEFF)
{
// Copy UNICODE data
iOffset = 1;
m_iSize = (dwSize-2) / sizeof(_TCHAR);
m_lpszText = (LPTSTR)malloc(m_iSize*sizeof(_TCHAR));
_tcscpy(m_lpszText, (LPTSTR)lpData+iOffset);
}
else if (dwFlag == 0xBFBBEF)
{
// Convert from UTF-8 to UNICODE data
iOffset = 3;
m_iSize = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)lpData+iOffset, dwSize-iOffset, NULL, 0);
m_lpszText = (LPTSTR)malloc(m_iSize*sizeof(_TCHAR));
int iget=MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)lpData+iOffset, dwSize-iOffset, m_lpszText, m_iSize);
m_lpszText[iget]='\0';
}
else
{
// Convert from ANSI to UNICODE data
iOffset = 0;
m_iSize = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpData+iOffset, dwSize, NULL, 0);
m_lpszText = (LPTSTR)malloc(m_iSize*sizeof(_TCHAR));
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpData+iOffset, dwSize, m_lpszText, m_iSize);
}
free(lpData);
// Update text
m_iSize += 2;
m_lpszText = (LPTSTR)realloc(m_lpszText, m_iSize*sizeof(_TCHAR));
m_lpszText[m_iSize-2] = '\r';
m_lpszText[m_iSize-1] = '\n';
}
说明
头部标志表示了3种类型:UNICODE、UTF8和ANSI,根据标志进行了不同的转换,不同的转换调用了不同的转换函数。转换时注意长度的处理,第二类里要把长度减去头部标志的长度,否则转出来的结果串的尾部会有乱码字符。
第一次转换是为了获取结果长度,第二次转换就是真正的内容转换。
最后强制在结果串尾部加了回车换行。
内存使用了Malloc和free方式,没有使用new和delete,这2者理论上都可以。