feof(fp)有兩個返回值:如果遇到檔案結束,函式feof(fp)的值為1,否則為0。
eof是檔案結束標誌的檔案。在文字檔案中,資料是以字元的ascⅱ**值的形式存放,ascⅱ**的範圍是0到255,不可能出現-1,因此可以用eof作為檔案結束標誌。
當把資料以二進位制形式存放到檔案中時,就會有-1值的出現,因此不能採用eof作為二進位制檔案的結束標誌。為解決這乙個問題,asci c提供乙個feof函式,用來判斷檔案是否結束。feof函式既可用以判斷二進位制檔案又可用以判斷文字檔案。
「c」語言的「feof()」函式和資料庫中「eof()」函式的運做是完全不同的。資料庫中「eof()」函式讀取當前指標的位置,「c」語言的「feof()」函式返回的是最後一次「讀操作的內容」。多年來把「位置和內容」相混,從而造成了對這一概念的似是而非。
那麼,位置和內容到底有何不同呢?舉個簡單的例子,比如有人說「你走到火車的最後一節車箱」這就是位置。而如果說「請你一直向後走,摸到鐵軌結束」這就是內容。也就是說用內容來判斷會「多走一節」。這就是完全依賴於「while(!feof(fp))」進行檔案複製時,目標文件總會比源文件「多出一些」的原因。
判斷檔案結束有兩種方法:eof和feof()
檢視stdio.h可以看到如下定義:
#define eof (-1)
#define _ioeof 0x0010
#define feof(_stream) ((_stream)->_flag & _ioeo
由此可以看出,這兩種方式的原理是不同的。
有人說eof只能用於文字檔案,其實不然,還要看定義的變數的型別。下面這段程式對文字檔案和二進位制檔案都可以:
int c;
while((c=fgetc(fp)) != eof)
如果讀到了ff,由於c定義為int型,所以實際上c=0x000000ff,不等於eof(-1=0xffffffff),因此不會誤判為檔案結尾。
但是如果把c定義為char型別,就有可能產生混淆了。
char c;
while((c=fgetc(fp)) != eof)
因為文字檔案中儲存的是ascii碼,而ascii碼中ff代表空值(blank),一般不使用,所以如果讀檔案返回了ff,說明已經到了文字檔案的結尾。但是如果是二進位制檔案,其中可能會包含ff,因此不能把讀到eof作為檔案結束的條件,此時只能用feof()函式。
在vc裡,只有當檔案位置指標(fp->_ptr)到了檔案末尾,然後再發生讀/寫操作時,標誌位(fp->_flag)才會被置為含有_ioeof。然後再呼叫feof(),才會得到檔案結束的資訊。因此,如果執行如下程式:
char c;
while(!feof(fp))
會發現多輸出了乙個ffffffff,原因就是在讀完最後乙個字元後,fp->flag仍然沒有被置為_ioeof,因而feof()仍然沒有探測到檔案結尾。直到再次呼叫fgetc()執行讀操作,feof()才能探測到檔案結尾。這樣就多輸出了乙個-1(即ffffffff)。
正確的寫法應該是:
char c;
c = fgetc(fp);
while(!feof(fp))
這麼說其實feof()是可以用eof來代替的嘍?不是,這裡還有乙個問題。fgetc返回-1時,有兩種情況:讀到檔案結尾或是讀取錯誤。因此我們無法確信檔案已經結束, 因為可能是讀取錯誤! 這時我們需要feof()。
**
常用的資料庫和資料庫操作
一般有下列一些資料庫 sqlite 輕量級的資料庫 fastdb 記憶體資料庫 mysql 常用效率高資料庫 access 微軟的檔案型資料庫 mssq 微軟的企業級資料庫 oracle 很笨重的資料庫,企業級別的。據高人告知,內部用c寫的,大量的巨集和goto db2 不推薦用,你用了就知道我為什...
資料庫和資料庫例項的概念
很多人都把這兩個概念弄混淆,認為mysql是資料庫,也是資料庫例項。這樣的理解在應用到oracle和sql server的時候可能是正確的,但是再mysql的體系結構中確是不適用的。那麼從概念上理解,該如何區分資料庫和資料庫例項呢?資料庫 資料庫是檔案的集合,是依照某種資料模型組織起來並存放於二級儲...
Hive 和資料庫的異同
摘要 由於 hive 採用了 sql 的查詢語言 hql,因此很容易將 hive 理解為資料庫。其實 從結構上來看,hive 和資料庫除了擁有類似的查詢語言,再無類似之處。本文將 從多個方面來闡述 hive 和資料庫的差異。資料庫可以用在 online 的應用中,但是 hive 是為資料倉儲而設計的...