急!崩溃!vc2005 向txt文件写入UNICODE字符乱码!
环境:WIN2003SP2 + VC2005(补丁版本SP.050727-7600)
一个操作日志程序,每个操作完成后既在窗口的监视编辑框中显示操作情况,又要将其写入到日志文本文件中。
这个项目以前是在VC6下做的,没有使用UNICODE,写入日志文件后用记事本读取时没有问题,不会乱码。
现在把这个项目升级到VC2005并且使用UNICODE,导致用记事本打开日志文件时除了数字和英文外,其余均乱码。
日志文件变量为CStdioFile类型。日志字符串变量为CString类型,将每步操作情况为一行,使用“\r\n”分行,最后将该字符串写到日志文件中
在VC6中的关键代码如下:
- C/C++ code
//VC6CStdioFile m_LogFile;//日志文件对象CString m_strLog;//日志内容字符串CString m_strLogFileName("DownLoad");//日志文件名称CFileException fe;//文件异常对象if(!m_LogFile.Open(m_strLogFileName ,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite|CFile::shareDenyNone|CFile::typeText ,&fe)){ char szErro[300] = {0}; fe.GetErrorMessage(szErro,300,NULL); CString strMessage; strMessage.Format("打开日志文件%s失败,无法记录操作过程!\r\n错误信息为:%s" ,m_strLogFileName,szErro); ::MessageBox(NULL,strMessage,"无法打开日志文件",MB_OK); return FALSE;}//开始记录m_strLog += "开始操作...\r\n";m_strLog += "操作一情况...\r\n";m_strLog += "操作二情况...\r\n";/*省略。。。*///写入日志文件m_LogFile.SeekToEnd();m_LogFile.WriteString(m_strLog + "\r\n"); m_LogFile.Flush();在VC2005中对应的代码如下(仅是使用_T()宏处理了一下字符串常量):
- C/C++ code
//VC2005,UNICODECStdioFile m_LogFile;//日志文件对象CString m_strLog;//日志内容字符串CString m_strLogFileName(_T("DownLoad"));//日志文件名称CFileException fe;//文件异常对象if(!m_LogFile.Open(m_strLogFileName ,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite|CFile::shareDenyNone|CFile::typeText ,&fe)){ TCHAR szErro[300] = {0}; fe.GetErrorMessage(szErro,300,NULL); CString strMessage; strMessage.Format(_T("打开日志文件%s失败,无法记录操作过程!\r\n错误信息为:%s") ,m_strLogFileName,szErro); ::MessageBox(NULL,strMessage,_T("无法打开日志文件"),MB_OK); return FALSE;}//开始记录m_strLog += _T("开始操作...\r\n");m_strLog += _T("操作一情况...\r\n");m_strLog += _T("操作二情况...\r\n");/*省略。。。*///写入日志文件m_LogFile.SeekToEnd();m_LogFile.WriteString(m_strLog + _T("\r\n")); m_LogFile.Flush();另外,还尝试了C的相关文件操作,同样写入后乱码。关键代码为:
- C/C++ code
#include <stdio.h>//打开日志文件(注意:去掉ccs=UNICODE也同样乱码!)FILE *pfile = _wfopen(L"DownLoad.log",L"at,ccs=UNICODE");//at:a表示追加,t表示文本方式//记录日志CString strLog(_T("操作开始...\r\n"));strLog += _T("操作一...\r\n");/*省略....*///将日志写入文本文件fwrite(strLog.GetBuffer(),sizeof(strLog.GetAt(0)),strLog.GetLength(),pfile);strLog.ReleaseBuffer();fflush(pfile);被这个问题缠了一上午了,已经焦头烂额,非常紧急!请朋友们帮忙!
[解决办法]
CStdioFile类,在Unicode下确实会出现这样的问题...
WriteString之前添加以下代码
- C/C++ code
unsigned short int feff=0xfeff; m_LogFile.Write(&feff,sizeof(short int));
[解决办法]
在日志文件头部写入0xfeff,以后就不要再写了,"\r\n"跟乱码没有关系。
[解决办法]
按二进制方式读写文件,如果存储为utf16-little endian格式,就是windows下面常规的unicode格式,需要在文件最前面写上0xff, 0xfe,这样记事本就认正确了。
[解决办法]
[解决办法]