电脑常规操作-《VC ANSI环境下按行读取ANSI等四种文本文件》_第1页
电脑常规操作-《VC ANSI环境下按行读取ANSI等四种文本文件》_第2页
电脑常规操作-《VC ANSI环境下按行读取ANSI等四种文本文件》_第3页
电脑常规操作-《VC ANSI环境下按行读取ANSI等四种文本文件》_第4页
电脑常规操作-《VC ANSI环境下按行读取ANSI等四种文本文件》_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

VC ANSI 环境下按行读取 ANSI、UNICODE 、UNICODE big endian、UTF-8 四种文本文件1.问题提出MFC 提供的文件类 CStdioFile,其中一个函数 ReadString 实现了文件的按行读取,但是不能满足不同类型的文本文件的按行读取,为了解决这一问题,笔者初步研究了一些编码知识,参考了网上的一些资料,实现了 CStdioFile 类的扩展类CStdioFileEx,完成了常见文本文件的按行读取(注明:不包括 DOC、PDF 等其他形式的文档 ).在此对网上分享编码经验的网友表示感谢,同时由于我编写的类还未经过严格测试,如有错误或方法过于复杂敬请各位指正。2.问题解决(1)四种常见文本文件编码方式研究ANSI、UNICODE 、UNICODE big endian、UTF-8 四种格式编码存在差别,简要介绍如下 :ANSI 编码 :无文件头(文件编码开头标志性字节) ANSI 编码字母数字占一个字节,汉字占两个字节,回车换行符 单字节 十六进制表示为 0d 0aUNICODE 编码:文件头,十六进制表示为 FF FE每一个字符都用两个字节编码回车换行符 双字节 000d 000aUnicode big endian 编码:文件头十六进制表示为 FE FF ,后面编码是把字符的高位放在前面,低位放在后面,正好和 Unicode 编码颠倒。回车换行符,双字节,十六进制表示为 0d00 0a00UTF-8 编码:文件头,十六进制表示为 EF BB BF。UTF-8 是 Unicode 的一种变长字符编码,数字、字母、回车、换行都用一个字节表示, 汉字占 3 个字节.回车换行符,单字节,十六进制表示为 0d 0a以中文“你好 “二字为例,各种类型的编码对应的十六进制格式(可由 EditPlus 查看 )如下图所示:由此可见上述的探讨是正确的。(2)按行读取上述四种格式文本文件的解决方案针对不同文件编码的特点,通过先检测文件头判断文件编码类型,然后根据文件类型分别调用不同的读取函数实现文件的按行读取。按行读取过程如下图所示:实现过程中,编写 CStdioFileEx 类,该类继承自 CStdioFile 类,覆盖了 CStdioFile 类的 BOOL ReadString(CString 33. class CStdioFileEx :public CStdioFile 34. 35. public: 36. CStdioFileEx(); 37. CStdioFileEx(FILE* pOpenStream); 38. CStdioFileEx(LPCTSTR lpszFileName, UINT nOpenFlags); 39. virtual CStdioFileEx(); 40. virtual BOOL Open( LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL); 41. public: 42. /文件类型值转换到字符串 43. CString FileTypeToString(); 44. /获取文件类型 45. TextCode GetFileType(); 46. /按行读取文件 47. BOOL ReadString(CString 48. /静态方法 获取文件类型 49. static TextCode GetFileType( LPCTSTR lpszFileName); 50. protected: 51. TextCode m_FileType;/保存文件类型 52. const static int PREDEFINEDSIZE;/预定义一行文件所需空间 53. protected: 54. /从 UTF-8 文件按行读取 55. BOOL ReadStringFromUTF8File(CString 56. /从 ANSI 文件按行读取 57. BOOL ReadStringFromAnsiFile(CString 58. /重 UNCIDOE、UNICODE big endian 文件读取 59. BOOL ReadStringFromUnicodeFile(CString 60. /UTF-8 字符串转换到 UNICODE 字符串 61. CString UTF8ToUnicode(byte *szUTF8); 62. /处理文件打开标志 63. UINT ProcessFlags(LPCTSTR lpszFileName, UINT 64. ; 65. 66. #endif / !defined(AFX_STDIOFILEEX_H_C1F1F96B_9417_4388_8D24_892EDFA2A616_INCLUDED_) / StdioFileEx.h: interface for/#if !defined(AFX_STDIOFILEEX_H_cpp view plaincopyprint?1. / StdioFileEx.cpp: implementation of the CStdioFileEx class. 2. / 3. / 4. 5. #include “stdafx.h“ 6. #include “StdioFileEx.h“ 7. 8. #ifdef _DEBUG 9. #undef THIS_FILE 10. static char THIS_FILE=_FILE_; 11. #define new DEBUG_NEW 12. #endif 13. 14. / 15. / Construction/Destruction 16. / 17. /*static*/ const int CStdioFileEx:PREDEFINEDSIZE=1024; 18. CStdioFileEx:CStdioFileEx():CStdioFile() 19. 20. m_FileType=ANSI;/指定默认类型 21. 22. CStdioFileEx:CStdioFileEx(FILE* pOpenStream):CStdioFile(pOpenStream) 23. 24. CString filepath=pOpenStream-_tmpfname;/? 尚不清楚 File*结构 25. m_FileType=GetFileType(filepath); 26. 27. CStdioFileEx:CStdioFileEx(LPCTSTR lpszFileName, UINT nOpenFlags):CStdioFile(lpszFileName,ProcessFlags(lpszFileName, nOpenFlags,m_FileType) ) 28. 29. 30. CStdioFileEx:CStdioFileEx() 31. 32. 33. 34. / - 35. /CStdioFileEx:GetFileType 静态方法 检测文本文件类型 36. / - 37. /*static */ TextCode CStdioFileEx:GetFileType(LPCTSTR lpszFileName) 38. 39. CFile file; 40. byte buf3;/unsigned char 41. TextCode tc; 42. try 43. 44. if(file.Open(lpszFileName,CFile:modeRead|CFile:shareDenyNone|CFile:typeBinary) 45. 46. file.Read(buf,3); 47. if(buf0=0xEF 49. else 50. if(buf0=0xFF 52. else 53. if(buf0=0xFE 55. else 56. tc=ANSI; 57. 58. else 59. tc=FILEERROR; 60. 61. catch (CFileException ex) 62. 63. CString errormsg; 64. errormsg.Format(_T(“操作文件%s 时发生异常!“),ex.m_strFileName); 65. AfxMessageBox(errormsg); 66. 67. return tc; 68. 69. / - 70. /CStdioFileEx:Readstring 按行读取文本文件 71. /根据不同文件类型 调用不同的读取函数 72. / - 73. BOOL CStdioFileEx:ReadString(CString 76. switch(m_FileType) 77. 78. case ANSI: 79. flag=ReadStringFromAnsiFile(rString); 80. break; 81. case UNICODE: 82. case UNICODEBIGENDIAN: 83. flag=ReadStringFromUnicodeFile(rString); 84. break; 85. case UTF8: 86. flag=ReadStringFromUTF8File(rString); 87. break; 88. case FILEERROR: 89. flag=FALSE; 90. break; 91. default: 92. break; 93. 94. return flag; 95. 96. / - 97. /CStdioFileEx:ReadstringFromAnsiFile 从 ANSI 文件读取字符串 98. / - 99. BOOL CStdioFileEx:ReadStringFromAnsiFile(CString 102. try 103. 104. flag=CStdioFile:ReadString(rString); 105. rString+=“rn“; 106. 107. catch(CFileException ex) 108. 109. CString errormsg; 110. errormsg.Format(_T(“操作文件%s 时发生异常!“),ex.m_strFileName); 111. AfxMessageBox(errormsg); 112. 113. return flag; 114. 115. / - 116. /CStdioFileEx:ReadstringFromUTF8File 从 UTF8 文件中按行读取 117. /由于 UTF-8 编码多字节编码且各种字符长度不同, 判断回车换行需要判断连续两个字节 118. / - 119. BOOL CStdioFileEx:ReadStringFromUTF8File(CString 122. byte cr=0x0d;/回车换行符 123. byte lf=0x0a; 124. byte temp2; 125. byte tempbyte; 126. byte *pbuf=new bytePREDEFINEDSIZE+1; 127. memset(pbuf,0,(PREDEFINEDSIZE+1)*sizeof(byte); 128. UINT readlen; 129. try 130. 131. /跳过文件头 移动文件指针 132. if (m_pStream 135. 136. index=0; 137. do 138. 139. memset(temp,0,2*sizeof(byte); 140. readlen=CFile:Read(temp,2);/CStdioFile:Read 效果不同 将省去回车符 0x0d 141. if(!readlen) 142. return FALSE; 143. /元素存贮到字节数组中 144. pbufindex+=temp0; 145. pbufindex+=temp1; 146. tempbyte=temp1; 147. /判断回车换行 148. if( ( tempbyte=cr 150. while (readlen=2 198. low = wchtemp0 199. wchtemp0 = ( low 8; 201. low = wchtemp1 202. wchtemp1 = ( low 8) | high; 203. 204. wChLineindex+=wchtemp0; 205. wChLineindex+=wchtemp1; 206. /判断回车换行 207. if(wchtemp0=wchcr 209. 210. while( (readlen=sizeof(wchar_t)*2) 211. wChLineindex=0; 212. CString strtext(wChLine,index); 213. rString=strtext; 214. if(rString.IsEmpty() 215. flag=FALSE; 216. 217. catch (CFileException ex) 218. 219. CString errormsg; 220. errormsg.Format(_T(“操作文件%s 时发生异常!“),ex.m_strFileName); 221. AfxMessageBox(errormsg); 222. 223. delete wChLine; 224. return flag; 225. 226. / - 227. /CStdioFileEx:UTF8ToUnicode UTF-8 字符串转换成 UNICODE 字符串 228. / - 229. CString CStdioFileEx:UTF8ToUnicode(byte *szUTF8) 230. 231. CString strret; 232. strret=_T(“); 233. if(!szUTF8) 234. return strret; 235. /获取转换后所需串空间的长度 236. int wcsLen = MultiByteToWideChar(CP_UTF8,0,(LPSTR)szUTF8,strlen(char*)szUTF8),NULL,0); 237. LPWSTR lpw=new WCHARwcsLen+1; 238. if(!lpw) 239. return strret; 240. memset(lpw,0,(wcsLen+1)*sizeof(wchar_t); 241. /实施转换 242. MultiByteToWideChar(CP_UTF8,0, (LPSTR)szUTF8, 243. strlen(char *)szUTF8), (LPWSTR)lpw, wcsLen); 244. CString str(lpw); 245. delete lpw; 246. return str; 247. 248. / - 249. /CStdioF

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论