今天在寫文件的時(shí)候發(fā)現(xiàn)fwrite的時(shí)候多出了一些亂碼,最后發(fā)現(xiàn)加個(gè)b,以二進(jìn)制的方式打開文件就解決了,google了.... 特記與此
在學(xué)習(xí)C語言文件操作后,我們都會(huì)知道打開文件的函數(shù)是fopen,也知道它的第二個(gè)參數(shù)是 標(biāo)志字符串。其中,如果字符串中出現(xiàn)'b',則表明是以打開二進(jìn)制(binary)文件,否則是打開文本文件。
那么什么是文本文件,什么是二進(jìn)制文件呢? 可能大多數(shù)人都沒有仔細(xì)考慮過。
在Windows和DOS系統(tǒng)中,狹義的文本文件是指擴(kuò)展名為txt的文件。實(shí)際上,那些沒有規(guī)定格式的,由可理解的的ASCII以及其他編碼文字組成的文件都是文本文件,如C源程序文件,HTML超文本,XML。除此之外的其他文件都是二進(jìn)制文件,如Word文件DOC,圖象格式文件JPG。
但是,所謂使用fopen標(biāo)志打開文本文件與二進(jìn)制文件的說法并不準(zhǔn)確。正確的說法應(yīng)該是--以文本方式和二進(jìn)制方式打開文件。因?yàn)槲覀冇脙煞N方式都可以任意的文件。
即使這樣,為什么還要區(qū)分兩種方式呢?
這是因?yàn)檫@兩種方式在讀寫文件時(shí)的操作是不一樣的。
二進(jìn)制方式很簡(jiǎn)單,讀文件時(shí),會(huì)原封不動(dòng)的讀出文件的全部?jī)?nèi)容,寫的時(shí)候,也是把內(nèi)存緩沖區(qū)的內(nèi)容原封不動(dòng)的寫到文件中。
而文本方式就不一樣了,在寫文件時(shí),會(huì)將換行符號(hào)CRLF(0x0D 0x0A)全部轉(zhuǎn)換成單個(gè)的0x0A,并且當(dāng)遇到結(jié)束符CTRLZ(0x1A)時(shí),就認(rèn)為文件已經(jīng)結(jié)束。相應(yīng)的,寫文件時(shí),會(huì)將所有的0x0A換成0x0D0x0A。
所以,若使用文本方式打開二進(jìn)制文件時(shí),就很容易出現(xiàn)文件讀不完整,或內(nèi)容不對(duì)的錯(cuò)誤。即使是用文本方式打開文本文件,也要謹(jǐn)慎使用,比如復(fù)制文件,就不應(yīng)該使用文本方式。
要特別注意的是,上面這樣的說法僅適用于DOS和Windows系統(tǒng)。在Unix和其他一些系統(tǒng)中,沒有文本方式和二進(jìn)制方式的區(qū)分,使不使用'b'標(biāo)志都是一樣的。這是由于不同操作系統(tǒng)對(duì)文本文件換行符的定義,和C語言中換行符的定義有所不同而造成的。
如上文已提到,DOS和Windows系統(tǒng)使用CRLF(0x0D 0x0A)雙字節(jié)作為文本文件換行符,而Unix文本文件的換行符只有一個(gè)字節(jié)LF(0x0A)為。在C語言中,也是以LF即'\n'為換行符。
由于DOS/Windows定義的換行符和C語言的不一致,C語言的標(biāo)準(zhǔn)輸入輸出函數(shù)適行讀寫文本文件時(shí),就適行了CRLF->LF的轉(zhuǎn)換。而Unix的定義和C語言的是一樣的,就不必轉(zhuǎn)換了。
那么,為什么會(huì)有定義不一致的情況呢,這純屬歷史原因。當(dāng)初C是在Unix上發(fā)展的,對(duì)換行的定義自然就一樣了。其后C被引入到DOS系統(tǒng),為了使原有的C程序能不加修改的讀寫DOS的文本文件,所以就在文件讀寫上做了修改。隨著DOS/Windows成為主流平臺(tái),這個(gè)當(dāng)初為了兼容而做的修改給眾多的C語言開發(fā)者添了這樣一個(gè)小小的麻煩。
from:
http://blog.chinaunix.net/u2/76292/showart.php?id=2140344
posted on 2010-01-05 20:23
chatler 閱讀(575)
評(píng)論(0) 編輯 收藏 引用 所屬分類:
Linux_Coding