亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1265 | 回復(fù): 0
打印 上一主題 下一主題

C語言中的文件操作 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2009-10-14 13:50 |只看該作者 |倒序瀏覽

C語言中的文件操作
寫在前
昨天帶實驗的時候發(fā)現(xiàn)很多同學(xué)在讀文件的時候老是要么多了一個字符,要么不能完全讀取……以前在用C的時候?qū)ξ募僮髯约阂矔龅揭恍﹩栴},但是都沒有去深究,昨晚突然心血來潮,決定把他弄清楚。
測試環(huán)境
windows
c-free3.0
C文件操作遇到的狀況
1.將一個文件讀到另一個文件,用“(ch = getc(fp)) != EOF”來判斷文件是否結(jié)束,如果文件是全英文文本的話絕對沒問題,新文件的大小和原文件大小一樣;但是如果是一些有中文字符或者是二進制文件,原文件沒讀完就結(jié)束。
2.將一個文件讀到另一個文件,用“!feof(fp)”判斷文件是否結(jié)束,不管原文件是什么類型的都可以將原文件全部讀完才結(jié)束,但是新文件的大小比原文件多了一個字節(jié)。
問題:在C里如何才能正確判斷文件結(jié)束??
探索
測試一,我寫了一個函數(shù)來試用EOF判斷文件結(jié)束的情況:
-------in.txt內(nèi)容如下---------
abcde
-------in.txt結(jié)束-------------
-------test1.c----------------
int main(int argc, char* argv[]){
    char ch;
    FILE* in;
    FILE* out;
   
    in = fopen("in.txt", "rb");  /* in.txt全為英文字符 */
    out = fopen("out.txt", "wb");
    while ((ch = getc(in)) != EOF){
         putc(ch, out);
    }
}
運行后結(jié)果是:out.txt的大小和in.txt的大小完全一樣。
然后修改in.txt如下,在原來的基礎(chǔ)上加入一些中文:
-------in.txt修改后的內(nèi)容如下---------
abcde
這是一個測試文件
測試中文字符
-------in.txt結(jié)束--------------------
運行后記過也是大小是一樣的。將源程序中的“in = fopen("in.txt", "rb");out = fopen("out.txt", "w");”改為“in = fopen("in.rar", "rb");out = fopen("out.rar", "wb");”,其中,in.rar是一個壓縮包文件,大小有4M多,運行程序后,得到的out.rar文件只有800多k,雙擊解壓也出現(xiàn)錯誤,無法解壓。
結(jié)論1:在C里,操作文件的時候,如果打開方式是“r”或者“w”,是以文本形式打開,也就是讀如內(nèi)存的字符值都是0-256之間,不可能出現(xiàn)-1,所以用EOF來判斷是可以的,但是如果以“rb”或者“wb”方式打開,以二進制讀入內(nèi)存或者寫入文件,出現(xiàn)負數(shù)是可能的,所以用EOF來判斷不能將文件讀完就已經(jīng)結(jié)束了。之所以在上面測試中有中文的in.txt文件沒有出錯,是因為在這個文中的中文恰好沒有一個的二進制碼是-1的;在后來的.rar測試中,就是讀到800多K時就遇到了-1,所以文件結(jié)束。
測試二,修改test1.c為test2.c
-------test2.c----------------
int main(int argc, char* argv[]){
    FILE* in;
    FILE* out;
   
    in = fopen("in.txt", "rb");
    out = fopen("out.txt", "wb");
    while (!feof(in)){
         putc(getc(in), out);
    }
}
不管是什么方式打開,打開什么文件,都能把原文件完全讀到新文件中,不過在新文件的末尾多了一個奇怪的字符(y上面多兩點,其二進制值是-1)。
在讀in.rar的時候,我把循環(huán)該成了永真循環(huán),執(zhí)行后用CTR+Z結(jié)束,out.rar大小為11M,比in.rar(4.2M)大了一倍多,但是我打開out.rar可以解壓,而且解壓出來的文件跟in.rar解壓出的文件的大小是一樣的。用UtralEdit打開out.rar發(fā)現(xiàn)從某一個時候開始,后面的所有二進制都是‘FF’(即-1),頓時明白out.rar比in.rar大的那部分其實全是-1。
結(jié)論2:在C里-1被定義成是文件結(jié)束符,所以在文件末尾多余的-1都不會影響文件的使用。
測試三,根據(jù)第二得到的結(jié)論,我想那如果一開始讀第一個字符的時候就讀到-1(文件結(jié)束符)會怎么樣呢?我又做了測試,
-------test3.c----------------
int main(int argc, char* argv[]){
    char ch= -1;
    FILE* in;
     
    in = fopen("in.txt", "wb");
    putc(ch, in);
}
然后又用記事本打開in.txt,在那個奇怪的字符(y上面多兩點,其二進制值是-1)后面自己加了一些英文字符。分別用test1.c和test2.c進行試驗,test1中新文件沒有內(nèi)容;test2全部都能讀到新文件中,只不過test2中的新文件后面仍讓有那個奇怪字符(y上面多兩點,其二進制值是-1)。很奇怪阿,如果-1是文件結(jié)束符的話,應(yīng)該在讀第一個字符的時候就停止了阿,怎么還能把-1后面的字符都讀到新文件中呢?又查閱了資料,自己猜想結(jié)論如下:雖然-1在C里被定義成文件結(jié)束符(EOF),但并不是說文件里出現(xiàn)了-1就表示文件結(jié)束,其實文件結(jié)束時候的-1是系統(tǒng)在讀到文件結(jié)束時候返回的一個值,而不是說系統(tǒng)讀到-1就知道文件結(jié)束(不知道有沒有把我的意思描述清楚),簡言之就是系統(tǒng)現(xiàn)知道文件結(jié)束了才返回-1,而不是先讀到-1才知道文件結(jié)束。所以,在文件中出現(xiàn)的-1并不是說文件結(jié)束,只有當真正文件指針指向文件結(jié)尾的時候系統(tǒng)返回的那個-1才表示文件結(jié)束。之所以在test1中不能讀是因為EOF=-1,用讀出來的-1跟EOF比較肯定是真的。(這個部分很難描述,大家可以去實際試驗下,有什么問題歡迎討論。)
第四,用fread()函數(shù)來判斷文件結(jié)束:
-------test4.c----------------
int main(int argc, char* argv[]){
    char ch;
    FILE* in;
    FILE* out;
   
    in = fopen("in.txt", "rb");
    out = fopen("out.txt", "wb");
    while (fread(&ch, sizeof(char), 1, in) == 1){
         putc(ch, out);
    }
}
這個方法能夠把文件都讀到新文件中,并且能有效判斷文件結(jié)束(不會在末尾添加上奇怪字符(y上面多兩點,其二進制值是-1)),在測試三中試驗的文本in.txt也能讀,而且是全部字符都讀到新文件中。
結(jié)論4:從一定程度上證明了測試三猜想的正確性。
最后
通過上面四個試驗,對C中的文件操作又有了更深的認識,在查資料的時候還發(fā)現(xiàn)文件操作跟操作系統(tǒng)、編譯器也有一定的關(guān)系。不管怎么說,如果用C操作文件的時候,建議用上面測試四中的方法。


本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u/10951/showart_2070117.html
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP