2010-02-27 29 views
8

我需要做的是使用unistd.h中的read函數逐行讀取文件 。我有這樣的時刻:unistd.h read()函數:如何逐行讀取文件?

n = read(fd, str, size); 

然而,這讀取到該文件的末尾,或最多字節大小數。 有沒有辦法讓我一次讀一行,停在換行符上? 這些線條都是可變長度的。

我只允許這兩個頭文件:

#include <unistd.h> 
#include <fcntl.h> 

的練習的要點是通過文件裏逐行讀取,並 輸出的每一行,因爲它的讀取基本上以模仿fgets() 和fputs()函數。

+0

您將需要使用'write()'來模擬'fputs()' - 你不能這樣做:) – 2010-02-27 20:30:09

回答

8

您可以逐字符讀入緩衝區並檢查換行符號(適用於Windows的\r\n和適用於Unix系統的\n)。

0

這是一個很好的問題,但只允許讀取功能並沒有幫助! :P

循環讀取調用以獲取固定數量的字節並搜索'\ n'字符,然後返回字符串的一部分(直到'\ n'),並將其餘部分(除\ n ')預先添加到下一個字符文件塊。

使用動態內存。

更大的緩衝區,更少的讀取調用(這是一個系統調用,所以不便宜,但現在有先發制人的內核)。

...

或者簡單修復的最大行長度,並用fgets,如果你需要快速...

0

如果您打開文本模式,那麼Windows「文件\ r \當文件被讀取時,n將被默默地轉換爲「\ n」。

如果你在Unix上,你可以使用非標準的gcc'getline()'功能。


getline()功能是在2008年POSIX

+3

OP希望從文件描述符而不是FILE流中讀取數據。 getline()從文件流中讀取,並且需要,這是不允許的。 – SzG 2013-10-06 18:06:42

0

嗯標準,它將從一個終端讀取線由行。

你有一些選擇是:

  • 編寫使用讀取功能,當它運行的數據,但一次只能返回一行給調用者
  • 使用中,做庫中的函數完全如此:fgets()
  • 一次只能讀取一個字節,所以你不要太過分。
1

不幸的是,讀取功能並不適合這種輸入。假設這是來自面試/家庭作業/練習的某種人爲要求,您可以嘗試模擬基於行的輸入,方法是通過分塊讀取文件並自行將其分割爲換行符,並在調用之間以某種方式維護狀態。如果仔細記錄功能的使用情況,您可以使用靜態位置指示器。

4

你會想要創建一個緩衝區長度的兩倍,你會支持你最長的行,你需要跟蹤你的緩衝區狀態。

基本上,每次你被要求換新行時,你都會從你當前的緩衝區位置開始掃描,尋找一個行尾標記。如果你找到一個,那好,那是你的路線。更新你的緩衝區指針並返回。

如果你打你的maxlength,那麼你返回一個截斷的行並將你的狀態改爲放棄。下次打電話時,您需要放棄直到下一行,然後輸入正常的讀取狀態。

如果您打開所讀內容的結尾,則需要讀入另一個maxline字符,如果觸到底部,則打包到緩衝區的開頭(即,您可能需要進行兩次讀取調用)然後繼續掃描。

以上全部假設您可以設置最大線路長度。如果你不能那麼你必須使用動態內存,並擔心如果一個緩衝區malloc失敗會發生什麼。另外,如果您在讀入緩衝區時碰到文件末尾,則需要始終檢查讀取結果。

1

如果您需要使用read()精確讀取1行(而不是超範圍),唯一通用的方法是每次讀取1個字節並循環,直到獲得換行字節。但是,如果您的文件描述符指向一個終端,並且它處於默認(規範)模式,則讀取將等待換行符,並且只要有一行可用,就會返回小於所請求的大小。但是,如果數據很快到達,它可能會返回多行,或者如果程序的緩衝區或內部終端緩衝區比行長度短,則可能返回的行少於1行。除非你真的需要避免超越(這有時很重要,如果你希望另一個進程/程序繼承文件描述符,並能夠從你離開的地方繼續閱讀),我會建議使用stdio函數或你的擁有自己的緩衝系統。對於基於行或逐字節的IO,使用read非常痛苦,很難正確使用。