2013-03-26 128 views
0

我有一個程序,它接受用戶給出的數據(int,浮點數和字符串)並將其寫入文本文件中。現在,我必須更新該寫入數據的一部分。文本文件編輯C

例如:

在文件中的行4我想改變前2個字(有一個intfloat)。我怎樣才能做到這一點?

有了我發現的信息,fseek()fputs()可以使用,但我不知道如何到達特定線路。

+0

你能改變那個數據文件的格式嗎?你認爲是JSON還是YAML?在C中有幾個JSON解析器,例如jansson – 2013-03-26 18:45:38

回答

1

你真的需要閱讀所有的文件,而忽略不需要什麼

(因爲我是一個起動機用C代碼的解釋可以理解的)。

fseek並不真正有用:它將文件定位在某個字節偏移處(相對於文件的開始或結尾)並且不知道行邊界。

實際上,文件中的行是一個不明確的概念。通常一行是由換行符('\n')結尾的字節序列(不同於換行符)。某些操作系統(Windows,MacOSX)以特殊的方式讀取文本文件(例如,實際文件包含\r\n以結束每一行,但C庫讓您錯過了您已閱讀\n)。

實際上,您可能想要使用line input routines,特別是getline(或者可能是fgets)。

如果您使用getline您應該關心free -ing行緩衝區。

如果您的文本文件具有非常規則的結構,那麼您可能需要fscanf數據(忽略您需要跳過的內容)而不關心行邊界。

如果您想絕對使用fseek(這是一個錯誤),您將不得不讀取文件兩次:第一次記住每行開始(或結束)的位置,第二次到fseek到行開始。但是,這對更新不起作用,因爲您不能在文件中插入字節。

實際上,最昂貴的操作是實際讀取磁盤。緩衝(部分由內核和<stdio.h>函數完成,部分由你在處理行時完成)可以忽略不計。

當然,你不能在文件中改變一些行。如果您需要這樣做,請處理文件以進行輸入,生成一些輸出文件(包含修改的輸入)並在完成時重命名。

順便說一句,你或許會對感興趣的索引文件,如GDBM等等......甚至像SqlLiteMariaDbmongodb等....,你可能會感興趣的標準文本的序列化格式像JSONYAML數據庫(他們都有很多庫,即使是C,也要處理它們)。

4

您不能在文件中「插入」字符。您將不得不創建程序,它將讀取整個文件,然後複製部分,然後插入到新文件,版本和文件的其餘部分。

0

fseek()用於隨機訪問文件,其中每個數據記錄具有相同的大小。通常數據是二進制的,而不是文本。

要解決您的特定問題,您需要一次讀取一行以找到您想要更改的行。進行更改的簡單方法是將這些行寫入臨時文件,將更改寫入相同的臨時文件,然後從原始文件中跳過要更改的部分,並將重置複製到臨時文件。最後,關閉原始文件,將臨時文件複製到它,然後刪除臨時文件。

這樣說的話,我建議你多瞭解隨機存取文件。這些在存儲所有相同大小的記錄時非常有用。如果您可以控制創建原始文件,這些可能會更適合您當前的目的。

+0

我不完全相信隨機訪問二進制文件總是一個很好的答案。它們當然會帶來自己的負擔:數據的不可移植性(除非您關心一些與架構無關的序列化格式),人類幾乎無法察覺,脆弱等等。 – 2013-03-26 19:21:27