




已閱讀5頁,還剩12頁未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
VC ANSI環(huán)境下按行讀取ANSI、UNICODE 、UNICODE big endian、UTF-8四種文本文件1.問題提出MFC提供的文件類CStdioFile,其中一個(gè)函數(shù)ReadString實(shí)現(xiàn)了文件的按行讀取,但是不能滿足不同類型的文本文件的按行讀取,為了解決這一問題,筆者初步研究了一些編碼知識(shí),參考了網(wǎng)上的一些資料,實(shí)現(xiàn)了CStdioFile類的擴(kuò)展類CStdioFileEx,完成了常見文本文件的按行讀?。ㄗ⒚鳎翰话―OC、PDF等其他形式的文檔).在此對(duì)網(wǎng)上分享編碼經(jīng)驗(yàn)的網(wǎng)友表示感謝,同時(shí)由于我編寫的類還未經(jīng)過嚴(yán)格測(cè)試,如有錯(cuò)誤或方法過于復(fù)雜敬請(qǐng)各位指正。2.問題解決(1)四種常見文本文件編碼方式研究ANSI、UNICODE 、UNICODE big endian、UTF-8四種格式編碼存在差別,簡要介紹如下:ANSI編碼:無文件頭(文件編碼開頭標(biāo)志性字節(jié)) ANSI編碼字母數(shù)字占一個(gè)字節(jié),漢字占兩個(gè)字節(jié),回車換行符 單字節(jié) 十六進(jìn)制表示為0d 0aUNICODE編碼:文件頭,十六進(jìn)制表示為FF FE每一個(gè)字符都用兩個(gè)字節(jié)編碼回車換行符 雙字節(jié) 000d 000aUnicode big endian編碼:文件頭十六進(jìn)制表示為FE FF ,后面編碼是把字符的高位放在前面,低位放在后面,正好和Unicode編碼顛倒?;剀嚀Q行符,雙字節(jié),十六進(jìn)制表示為0d00 0a00UTF-8 編碼:文件頭,十六進(jìn)制表示為EF BB BF。UTF-8是Unicode的一種變長字符編碼,數(shù)字、字母、回車、換行都用一個(gè)字節(jié)表示,漢字占3個(gè)字節(jié).回車換行符,單字節(jié),十六進(jìn)制表示為0d 0a以中文你好二字為例,各種類型的編碼對(duì)應(yīng)的十六進(jìn)制格式(可由EditPlus查看)如下圖所示:由此可見上述的探討是正確的。(2)按行讀取上述四種格式文本文件的解決方案針對(duì)不同文件編碼的特點(diǎn),通過先檢測(cè)文件頭判斷文件編碼類型,然后根據(jù)文件類型分別調(diào)用不同的讀取函數(shù)實(shí)現(xiàn)文件的按行讀取。按行讀取過程如下圖所示:實(shí)現(xiàn)過程中,編寫CStdioFileEx類,該類繼承自CStdioFile類,覆蓋了CStdioFile類的BOOL ReadString(CString& rString)方法,從而實(shí)現(xiàn)了文件按行讀取。(3)CStdioFileEx類的實(shí)現(xiàn)代碼代碼清單:cpp view plaincopyprint?1. /StdioFileEx.h:interfacefortheCStdioFileExclass. 2. / 3. / 4. 5. #if!defined(AFX_STDIOFILEEX_H_C1F1F96B_9417_4388_8D24_892EDFA2A616_INCLUDED_) 6. #defineAFX_STDIOFILEEX_H_C1F1F96B_9417_4388_8D24_892EDFA2A616_INCLUDED_ 7. 8. #if_MSC_VER1000 9. #pragmaonce 10. #endif/_MSC_VER1000 11. /- 12. /程序用途:按行讀取常見(包括ANSI、UNICODE、UNICODEbigendian、UTF-8)格式的文本文件 13. /程序作者:湖北師范學(xué)院計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院王定橋 14. /核心算法:CStdioFileEx繼承自CStdioFile,覆蓋CStdioFile的BOOLReadString(CString&rString)方法, 15. /根據(jù)不同文件編碼特征,尋找文件回車換行符判斷讀取行結(jié)束,文件結(jié)束符判斷文件結(jié)束 16. /檢測(cè)不同文件編碼頭部,獲取文件類型后調(diào)用不同的讀取函數(shù) 17. /測(cè)試結(jié)果:在Windows7VC6.0環(huán)境下測(cè)試上述四種格式的txt文件通過 18. /尚未完成:未重載CStdioFile的virtualLPTSTRReadString(LPTSTRlpsz,UINTnMax)方法 19. /未完成WriteString方法,未在VCUNICODE環(huán)境下的測(cè)試 20. /制作時(shí)間:2012-04-19 21. /代碼版權(quán):代碼公開供學(xué)習(xí)交流使用歡迎指正錯(cuò)誤改善算法 22. /- 23. #includestdafx.h 24. /文本文件類型枚舉值 25. typedefenumTextCodeType26. 27. UTF8=0,28. UNICODE=1,29. UNICODEBIGENDIAN=2,30. ANSI=3,31. FILEERROR=432. TextCode;33. classCStdioFileEx:publicCStdioFile34. 35. public:36. CStdioFileEx();37. CStdioFileEx(FILE*pOpenStream);38. CStdioFileEx(LPCTSTRlpszFileName,UINTnOpenFlags);39. virtualCStdioFileEx();40. virtualBOOLOpen(LPCTSTRlpszFileName,UINTnOpenFlags,CFileException*pError=NULL);41. public:42. /文件類型值轉(zhuǎn)換到字符串 43. CStringFileTypeToString();44. /獲取文件類型 45. TextCodeGetFileType();46. /按行讀取文件 47. BOOLReadString(CString&rString);48. /靜態(tài)方法獲取文件類型 49. staticTextCodeGetFileType(LPCTSTRlpszFileName);50. protected:51. TextCodem_FileType;/保存文件類型 52. conststaticintPREDEFINEDSIZE;/預(yù)定義一行文件所需空間 53. protected:54. /從UTF-8文件按行讀取 55. BOOLReadStringFromUTF8File(CString&rString);56. /從ANSI文件按行讀取 57. BOOLReadStringFromAnsiFile(CString&rString);58. /重UNCIDOE、UNICODEbigendian文件讀取 59. BOOLReadStringFromUnicodeFile(CString&rString);60. /UTF-8字符串轉(zhuǎn)換到UNICODE字符串 61. CStringUTF8ToUnicode(byte*szUTF8);62. /處理文件打開標(biāo)志 63. UINTProcessFlags(LPCTSTRlpszFileName,UINT&nOpenFlags,TextCode&tc);64. ;65. 66. #endif/!defined(AFX_STDIOFILEEX_H_C1F1F96B_9417_4388_8D24_892EDFA2A616_INCLUDED_)cpp view plaincopyprint?1. /StdioFileEx.cpp:implementationoftheCStdioFileExclass. 2. / 3. / 4. 5. #includestdafx.h 6. #includeStdioFileEx.h 7. 8. #ifdef_DEBUG 9. #undefTHIS_FILE 10. staticcharTHIS_FILE=_FILE_;11. #definenewDEBUG_NEW 12. #endif 13. 14. / 15. /Construction/Destruction 16. / 17. /*static*/constintCStdioFileEx:PREDEFINEDSIZE=1024;18. CStdioFileEx:CStdioFileEx():CStdioFile()19. 20. m_FileType=ANSI;/指定默認(rèn)類型 21. 22. CStdioFileEx:CStdioFileEx(FILE*pOpenStream):CStdioFile(pOpenStream)23. 24. CStringfilepath=pOpenStream-_tmpfname;/?尚不清楚File*結(jié)構(gòu) 25. m_FileType=GetFileType(filepath);26. 27. CStdioFileEx:CStdioFileEx(LPCTSTRlpszFileName,UINTnOpenFlags):CStdioFile(lpszFileName,ProcessFlags(lpszFileName,nOpenFlags,m_FileType)28. 29. 30. CStdioFileEx:CStdioFileEx()31. 32. 33. 34. /- 35. /CStdioFileEx:GetFileType靜態(tài)方法檢測(cè)文本文件類型 36. /- 37. /*static*/TextCodeCStdioFileEx:GetFileType(LPCTSTRlpszFileName)38. 39. CFilefile;40. bytebuf3;/unsignedchar 41. TextCodetc;42. try43. 44. if(file.Open(lpszFileName,CFile:modeRead|CFile:shareDenyNone|CFile:typeBinary)45. 46. file.Read(buf,3);47. if(buf0=0xEF&buf1=0xBB&buf2=0xBF)48. tc=UTF8;49. else50. if(buf0=0xFF&buf1=0xFE)51. tc=UNICODE;52. else53. if(buf0=0xFE&buf1=0xFF)54. tc=UNICODEBIGENDIAN;55. else56. tc=ANSI;57. 58. else59. tc=FILEERROR;60. 61. catch(CFileExceptionex)62. 63. CStringerrormsg;64. errormsg.Format(_T(操作文件%s時(shí)發(fā)生異常!),ex.m_strFileName);65. AfxMessageBox(errormsg);66. 67. returntc;68. 69. /- 70. /CStdioFileEx:Readstring按行讀取文本文件 71. /根據(jù)不同文件類型調(diào)用不同的讀取函數(shù) 72. /- 73. BOOLCStdioFileEx:ReadString(CString&rString)74. 75. BOOLflag=FALSE;76. switch(m_FileType)77. 78. caseANSI:79. flag=ReadStringFromAnsiFile(rString);80. break;81. caseUNICODE:82. caseUNICODEBIGENDIAN:83. flag=ReadStringFromUnicodeFile(rString);84. break;85. caseUTF8:86. flag=ReadStringFromUTF8File(rString);87. break;88. caseFILEERROR:89. flag=FALSE;90. break;91. default:92. break;93. 94. returnflag;95. 96. /- 97. /CStdioFileEx:ReadstringFromAnsiFile從ANSI文件讀取字符串 98. /- 99. BOOLCStdioFileEx:ReadStringFromAnsiFile(CString&rString)100. 101. BOOLflag;102. try103. 104. flag=CStdioFile:ReadString(rString);105. rString+=rn;106. 107. catch(CFileExceptionex)108. 109. CStringerrormsg;110. errormsg.Format(_T(操作文件%s時(shí)發(fā)生異常!),ex.m_strFileName);111. AfxMessageBox(errormsg);112. 113. returnflag;114. 115. /- 116. /CStdioFileEx:ReadstringFromUTF8File從UTF8文件中按行讀取 117. /由于UTF-8編碼多字節(jié)編碼且各種字符長度不同,判斷回車換行需要判斷連續(xù)兩個(gè)字節(jié) 118. /- 119. BOOLCStdioFileEx:ReadStringFromUTF8File(CString&rString)120. 121. longindex;122. bytecr=0x0d;/回車換行符 123. bytelf=0x0a;124. bytetemp2;125. bytetempbyte;126. byte*pbuf=newbytePREDEFINEDSIZE+1;127. memset(pbuf,0,(PREDEFINEDSIZE+1)*sizeof(byte);128. UINTreadlen;129. try130. 131. /跳過文件頭移動(dòng)文件指針 132. if(m_pStream&(GetPosition()=0)133. 134. CStdioFile:Seek(3*sizeof(byte),CFile:begin);135. 136. index=0;137. do138. 139. memset(temp,0,2*sizeof(byte);140. readlen=CFile:Read(temp,2);/CStdioFile:Read效果不同將省去回車符0x0d 141. if(!readlen)142. returnFALSE;143. /元素存貯到字節(jié)數(shù)組中 144. pbufindex+=temp0;145. pbufindex+=temp1;146. tempbyte=temp1;147. /判斷回車換行 148. if(tempbyte=cr&temp0=lf)|(temp0=cr&temp1=lf)149. break;150. while(readlen=2&index8;198. low=wchtemp0&0x00FF;199. wchtemp0=(low8;201. low=wchtemp1&0x00FF;202. wchtemp1=(low8)|high;203. 204. wChLineindex+=wchtemp0;205. wChLineindex+=wchtemp1;206. /判斷回車換行 207. if(wchtemp0=wchcr&wchtemp1=wchlf)208. break;209. 210. while(readlen=sizeof(wchar_t)*2)&indexPREDEFINEDSIZE);211. wChLineindex=0;212. CStringstrtext(wChLine,index);213. rString=strtext;214. if(rString.IsEmpty()215. flag=FALSE;216. 217. catch(CFileExceptionex)218. 219. CStringerrormsg;220. errormsg.Format(_T(操作文件%s時(shí)發(fā)生異常!),ex.m_strFileName);221. AfxMessageBox(errormsg);222. 223. deletewChLine;224. returnflag;225. 226. /- 227. /CStdioFileEx:UTF8ToUnicodeUTF-8字符串轉(zhuǎn)換成UNICODE字符串 228. /- 229. CStringCStdioFileEx:UTF8ToUnicode(byte*szUTF8)230. 231. CStringstrret;232. strret=_T();233. if(!szUTF8)234. returnstrret;235. /獲取轉(zhuǎn)換后所需串空間的長度 236. intwcsLen=MultiByteToWideChar(CP_UTF8,0,(LPSTR)szUTF8,strlen(char*)szUTF8),NULL,0);237. LPWSTRlpw=newWCHARwcsLen+1;238. if(!lpw)239. returnstrret;240. memset(lpw,0,(wcsLen+1)*sizeof(wchar_t);241. /實(shí)施轉(zhuǎn)換 242. MultiByteToWideChar(CP_UTF8,0,(LPSTR)szUTF8,243. strlen(char*)szUTF8),(LPWSTR)lpw,wcsLen);244. CStringstr(lpw);245. deletelpw;246. returnstr;247. 248. /- 249. /CStdioFileEx:GetFileType獲取文件類型 250. /- 251. TextCodeCStdioFileEx:GetFileType()252. 253. returnm_FileType;254. 255. /- 256. /CStdioFileEx:FileTypeToString文件類型枚舉值轉(zhuǎn)換為字符串值 257. /- 258. CStringCStdioFileEx:FileTypeToString()259. 260. CStringstrtype;261. switch(m_FileType)262. 263. caseANSI:264. strtype.Format(%s,_T(ANSI);265. break;266. caseUTF8:267. strtype.Format(%s,_T(UTF8);268. break;269. caseUNICODE:270. strtype.Format(%s,_T(UNICODE);271. break;272. caseUNICODEBIGENDIAN:273. strtype.Format(%s,_T(UNICODEbigendian);274. break;275. caseFILEERROR:276. strtype.Format(%s,_T(FILEERROR);277. break;278. default:279. break;280. 281. returnstrtype;282. 283. /- 284. /CStdioFileEx:Open重載父類的文件打開操作改變不同類型文件的打開方式 285. /- 286. BOOLCStdioFileEx:Open(LPCTSTRlpszFileName,UINTnOpenFlags,CFileException*pError)287. 288. ProcessFlags(lpszFileName,nOpenFlags,m_FileType);/處理文件打開方式 289. returnCStdioFile:Open(lpszFileName,nOpenFlags,pError);290. 291. /- 292. /CStdioFileEx:ProcessFlags處理不同文件的打開方式 293. /ANSI文件采用文本讀取,UNICODE、UNICDOEbigendian、UTF-8采用二進(jìn)制方式讀取 294. /- 295. UINTCStdioFileEx:ProcessFlags(LPCTSTRlpszFileName,UINT&nOpenFlags,TextCode&tc)296. 297. tc=CStdioFileEx:GetFileType(lpszFileName);298. if(nOpenFlags&CFile:modeReadWrite)|(nOpenFlags&CFile:modeRead)299. 300. switch(tc)301. 302. caseANSI:303. nOpenFlags|=CFile:typeText;304. nOpenFlags&=CFile:typeBinary;305. break;306. caseUTF8:307. nOpenFlags|=CFile:typeBinary;308. nOpenFlags&=CFile:typeText;309. break;310. caseUNICODE:311. nOpenFlags|=CFile:typeBinary;312. nOpenFlags&=CFile:typeText;313. break;314. caseUNICODEBIGENDIAN:315. nOpenFlags|=CFile:typeBinary;316. nOpenFlags&=CFile:typeText;317. break;318. caseFILEERROR:319. break;320. default:321. break;322. 323. 324. nOpenFlags|=CFile:shareDenyNone;325. returnnOpenFlags;326. 3.運(yùn)行結(jié)果(1)測(cè)試部分核心代碼/打開文件cpp view plaincopyprint?1. voidCReadStringDlg:OnBtnOpen()2. 3. /TODO:Addyourcontrolnotificationhandlercodehere 4. charszFilter=TextFiles(*.txt)|*.txt|AllFiles(*.*)|*.*|;5. CFileDialogfiledlg(TRUE,txt,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter,this);6. if(IDOK=filedlg.DoModal()7. 8. m_strPath=filedlg.GetPathName();9. UpdateData(FALSE);10. m_ctrlEdit.SetSel(0,-1);11. m_ctrlEdit.Clear();12. if(m_stdiofileex.Open(m_strPath,CFile:modeRead)13. 14. m_strFileType=m_stdiofileex.FileTypeToString();15. UpdateData(FALSE);16. 17. else18. 19. MessageBox(_T(讀取文件失敗!);20. 21. 22. 23. /讀取文件 24. voidCReadStringDlg:OnBtnRead()25. 26. /TODO:Addyourcontrolnotificationhandlercodehere
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 提高公司財(cái)務(wù)團(tuán)隊(duì)服務(wù)水平的培訓(xùn)計(jì)劃
- 提升前臺(tái)溝通技巧的工作計(jì)劃
- 醫(yī)院財(cái)務(wù)管理優(yōu)化的策略與效果計(jì)劃
- 學(xué)習(xí)資源共享平臺(tái)建設(shè)計(jì)劃
- 《貴州創(chuàng)泰礦業(yè)有限公司修文縣龍場(chǎng)鎮(zhèn)高倉老二洞鋁鐵礦山礦產(chǎn)資源綠色開發(fā)利用方案(三合一)》專家組評(píng)審意見
- 第二單元課題2氧氣-教學(xué)設(shè)計(jì)-2024-2025學(xué)年九年級(jí)化學(xué)人教版上冊(cè)
- 2025年鎮(zhèn)江道路運(yùn)輸從業(yè)資格證模擬考試年新版
- 2025年湖州資格證模擬考試
- 2025年湖北貨車資格證考試題
- 2025年遼陽貨運(yùn)從業(yè)資格證模擬考試下載題
- 《幼兒園課程》試題庫及答案2021
- 干細(xì)胞技術(shù)與臨床應(yīng)用0718合一康
- 鍋爐房風(fēng)險(xiǎn)管控措施告知牌
- 苔花如米小“艷過”牡丹開——名著導(dǎo)讀之《簡愛》
- 《西方服裝發(fā)展史》PPT課件(完整版)
- 《食管裂孔疝》PPT課件(完整版)
- 家庭醫(yī)生工作室和家庭醫(yī)生服務(wù)點(diǎn)建設(shè)指南
- 魯班尺和丁蘭尺速查表
- 企業(yè)年會(huì)搞笑相聲劇本《治病》
- 為夢(mèng)想插上翅膀主題班會(huì)PPT授課課件
- JJF-1069-2000-法定計(jì)量檢定機(jī)構(gòu)考核規(guī)范
評(píng)論
0/150
提交評(píng)論