linux c 檔案操作
手把手教會你c語言檔案操作(1)
2. 檔案操作位置是否到達了文件末尾?
1.1 偏移操作
說是說指標偏移,將其稱之為「尋找操作位置」也未嘗不可,也更加容易記住這個函式。為什麼這麼說呢,尋找 ----- seek,不難猜出這個函式就是 fseek。
來看看函式原型:
int
fseek
(file *fp,
long offset,
int origin)
; @fp: 要偏移操作位置的檔案指標
@offset: 偏移大小
@origin:
seek_set
0 開頭
seek_cur
1 當前
seek_end
2 末尾
返回值:成功返回0,失敗返回-
1。
關於第二引數 offset ,我們注意一下他的型別是 long 而不是 unsigned long ,這說明這個引數可能是負數,那就很奇怪了呀,可以使正數、負數、0,那怎麼確定是哪個呢?
那如果我告訴你這個正負性是指偏移方向,負數向左,正數向右偏移的話,你能想到什麼呢?
沒錯,這個引數是基於第 3 個引數的,在第 3 個引數的位置的基礎上前後移動 offset 個位元組。
做個試驗
假設我有乙個 a.txt 檔案,裡面儲存著萬年新手** hello world。
那麼下面的語句讀取到的是什麼內容呢?
if(!
fseek
(fp,0,
seek_set))
}if(!
fseek
(fp,-5
,seek_cur))
}if(!
fseek
(fp,-6
,seek_end))
}
buffer = hello
buffer = hello
buffer = world
分析一下
第乙個大 if 的意思是:從頭開始,不加左右偏移,讀取 5 個位元組儲存在 buffer 中。
第二個大 if 執行時,當前檔案操作指標在 hello 的 o 之後,再讀取內容時就是空格開始了。此時的 fseek 語句是指:指標先保持當前位置不動,然後加上向前偏移 5 個位元組開始讀取 5 個位元組內容。
第三個大 if 的意思就跟簡單了,偏移至最後之後,已經讀取不到內容了,已經到了文件末尾(end of file),也就是再標頭檔案中定義的 eof 巨集值。在這個基礎上向前偏移 6 個位元組讀取 5 個位元組。
是不是覺得不夠直觀,想要看到直接一點的資料?這不,他來了。
1.2 獲取當前操作位置與檔案開頭之間的位元組數
函式原型:
long
ftell
(file *fp)
;返回值:成功返回當前操作位置與開頭的位元組數,失敗返回-
1;
嗯,這個函式多簡單是吧,我們把這個函式加入到上面的**中。
就是這樣了,這個小函式還是比較簡單的。
1.3 面試題:給出乙個檔名,返回該檔案的位元組數(檔案大小)。
相信有童鞋已經想到了,將檔案操作指標偏移至檔案末尾,再用 ftell 獲取其與檔案開頭的值即可。
**如下:
long
getfilesize
(const
char
*file_name)
file *fp =
fopen
(file_name,
"r");if
(fp ==
null)if
(!fseek
(fp,0,
seek_end))
else
}
到這裡應該能夠理解 fseek 的使用了吧,那我們再順便提一提上面提到的 eof。
當我們使用 fread 去讀取檔案時,相信大家還記得我們是如何判斷操作是否成功的對吧。不過呢,不知道各位有沒有注意到有個特殊情況 ------- 檔案操作位置位於文件末尾。由於此時的位置之後已經沒有內容可讀了,fread 自然而然返回了 0,而我們卻把它當做錯誤處理掉了,想想好像有點不太合適?
那我們如何判斷呢?鏘鏘,就是這個巨集 ---- eof,全稱為:end of file。
同時,還有兩個小函式一併解決了吧:
int
feof
(file *fp)
;返回值:成功返回真;失敗返回假。
intferror
(file *fp)
;返回值:成功返回真;失敗返回假。
不作過多解釋了,依舊是那個只有 「hello world.」 的 a.txt 檔案,加上這兩個保險的話就是這樣子滴:
int
main()
char buf[5]
=;int ret;
/***********************************/
while(1
)// 讀完為止,或者是出錯停下if(
ferror
(fp)
)// 沒有到文件末尾多半就是出錯啦,不過既然說到這個函式就給個面子吧。
}printf
("read buf = %s\n"
, buf)
;// 看看每次讀取到了什麼?
}// 不管是出錯還是讀取完畢,關閉檔案的操作必不可少,養成好習慣哦。
/****************************************/
return0;
}
執行結果:
read buf = h
read buf = e
read buf = l
read buf = l
read buf = o
read buf =
read buf = w
read buf = o
read buf = r
read buf = l
read buf = d
read buf =
.end of file, nothing to read.
嗯,到這的話其實都差不多說完了,寫入檔案也是一樣的道理,其實只要你像我這兩篇文章的思路,大膽去將介面試一試,提出問題,用執行結果來佐證或是推翻你的猜測,我覺得已經沒有什麼是很難的了。
好吧,本文最後炒一炒冷飯,不使用檔案操作指標偏移,僅使用 fread 、feof 和 ferror 來統計檔案大小又該怎麼寫呢?
手把手教會你C語言檔案操作(1)
在c語言學習過程中,對於資料的儲存是無法避免的問題之一。我們學習了用陣列來儲存某一種型別資料,用結構體來儲存多種不同型別資料,但是這些都是程式中的容器,程式退出後這些資料也就隨之消失了。所以我們嘗試尋找一種方式,能夠將資料儲存與程式分離開來。在 linux 中有這麼一句話 一切皆檔案。所以我們嘗試將...
手把手教會你C語言檔案操作(3)
如題所說,這篇博文就來聊聊檔案的寫入,也就是將資料從程式中儲存至指定檔案當中。手把手教會你c語言檔案操作 1 手把手教會你c語言檔案操作 2 檔案操作相關函式 好吧,我也知道沒啥人看我的寫的部落格,就不自取其辱了,直接進入正題吧。首先要明確一下這個操作許可權指的是什麼。它是指我們用fopen開啟某個...
手把手入門C語言 列舉
列舉中的變數是遞增的 預設是0開始 首元素的值是0 include include 列舉中的變數是遞增的 預設是0開始 首元素的值是0 定義乙個列舉 enum weekday main 測試列舉中的變數是遞增的 修改下面的 monday 0,tuesday,wednesday,thursday,fr...