很长时间没有更新文章了,今天静下心来写MiniNote,解决一些BUG。之前有朋友反映说打开文本文件功能有问题,经过检查还是Unicode问题。烦死了。。。
于是从入口开始调整,重写了文本文件读写类,解决了读取Unicode和Ansi文本的问题。解决办法就是通过检查文本文本前两个字节来实现(编码格式介绍
http://www.mini188.com/showtopic-971.aspx),暂时测试是可以用的。下面就把方法简单的介绍下,希望能帮助到别的朋友。
1、如何判断编码格式:
- void M8NoteFileReader::GetTextCode(TCHAR *filename)
- {
- if (FileExists(filename))
- {
- fstream openfile;
- openfile.open(filename, ios::in | ios::binary);
- openfile.seekg(0, ios::beg);
- char *code = new char[2];
- openfile.read(code, 2);
- openfile.close();
-
- unsigned char cc = (unsigned char)code[0];
- unsigned char cc1 = (unsigned char)code[1];
- if ((cc == 0xFF) && (cc1 == 0xFE))
- {
- m_TextCode = ttcUnicode;
- }
- else if ((cc == 0xFE) && (cc1 == 0xFF))
- {
- m_TextCode = ttcUnicodeBigEndian;
- }
- else if ((cc == 0xEF) && (cc1 == 0xBB))
- {
- m_TextCode = ttcUnicode;
- }
- else
- {
- m_TextCode = ttcAnsi;
- }
- }
- }
复制代码GetTextCode函数即是判断的主体函数了,看代码先是使用fstream类来读取文件,获取两个字节大小的内容存放于code变量中,即BOM结构。
接着将code中两个字节分别转换为无符号类型,这一点很重要,在这个问题上我弄了二个多小时没弄明白,后为是Lamian、邵燃两位老兄帮忙解决了。就是要使用无符号类型才能正确获取到值。
有了这两具字节就可以判断了,后面的if语句就是干这个活的。
其中的m_TextCode是我定义的一个emnu用于表示编码格式的类型,如下:
enum TextTypeCode{ttcAnsi, ttcUnicode, ttcUnicodeBigEndian, ttcUtf8};
知道所读文本文件的编码类型后就可以通过相应的类来获取文本内容了,由于目前仅用到了Unicode和Ansi两种,所以就只实现了两个方法,分别用于读取Unicode和ANSI字符串。
- //读取Unicode
- void M8NoteFileReader::ReadFileByUnicode()
- {
- if (FileExists(m_FileName))
- {
- wifstream ofile;
- ofile.open(m_FileName.C_Str(), ios::in | ios ::binary);
- if (ofile.is_open())
- {
- ofile.seekg(0, ios::end);
- int nLen = ofile.tellg();
- ofile.seekg(2, ios::beg);
- wchar_t *tmpstr = new wchar_t[nLen + 1];
- ofile.read(tmpstr, nLen);
- tmpstr[nLen] = '\0\0';
- m_Text = tmpstr;
- }
- ofile.close();
- }
- }
- //读取Ansi文本
- void M8NoteFileReader::ReadFileByAnsi()
- {
- //读取文本
- ifstream file1;
- file1.open(m_FileName.C_Str(), ios::in | ios::binary);
- if (file1.is_open())
- {
- file1.seekg(0, ios::end);
- int nLen = file1.tellg();
- char *ss = new char[nLen+1];
- file1.seekg(0, ios::beg);
- file1.read(ss, nLen);
- ss[nLen] = '\0';
- m_Text = chr2wch(ss);
- }
- file1.close();
- }
复制代码用wifstream来读取unicode,而用ifstream来读ansi再通过转换函数转换成unicode供控件显示。转换在以前文章中说明过。
最后将取出的内容存放于m_Text中,在这里m_Text就是魅族的 CMzString。
读取就这么简单说明,接下来解决保存的问题。