2011-06-21 130 views
4

我正在使用C/UNIX並且有一個包含記錄數的輸入文件。我已將每條記錄映射到一個結構,並通過在數據庫的記錄中添加缺少的信息將結構寫入輸出文件。將結構寫入文件C

我的問題是寫結構(由字符數組組成)回到文件。我正在使用

fwrite(&record, sizeof(record), 1, out); 
    fwrite("\n", 1, 1, outfd); 

這將在每個成員之後將數據寫入輸出文件中,終止NULL'\ 0'。請讓我知道如何在每個成員之後沒有終止'\ 0'的情況下將此結構寫入文件。

+2

請提供結構定義,以便我們知道您正在使用什麼。此外,你正在試圖處理你剛寫下的數據。如果它被寫入另一個C程序,這可能是一個功能。 –

+2

請注意,這樣做意味着您的格式不可移植。 – jamesdlin

回答

5

我會想象那些0是字符數組的一部分 - 它們在每個C字符串的末尾。如果您需要將字符串寫入文件而不用零,則可以編寫單個字符數組,只寫入字符而不寫入尾部零(您可以使用strlen()查找此長度),即,

fwrite (theCharArray,1,strlen(theCharArray),out);

但是你可能需要寫一些關於每個字符串到文件長度的信息。

+0

謝謝歐內斯特,是的,這是真的,那些尾隨'\ 0'是字符數組的一部分。編寫單個字符串是唯一的解決方案。該結構非常大,有100名成員。請建議。 –

+1

@Jerry Coffin建議使用由'offsetof'和一個循環計算出來的數值數組;這實際上會導致*更多*,儘管稍微簡單一些的代碼行。我可以想到的一個瘋狂的事情是,如果'struct'完全由char數組組成,那麼你可以有一個迭代sizeof(struct)次的for循環,在每一步前進一個指針,並寫入非零字符到文件,一次一個。整個過程只需要幾行代碼,並且對結構的修改會很有效。缺點是表現可能不會那麼好。 –

3

這會寫出一個與存儲在內存中一樣的record - 但編譯器在成員之間自由插入填充,如果存在,則會寫出填充字節中發生的任何值。許多(大多數?)編譯器有不可移植的方法來阻止它們插入該填充 - MSVC使用#pragma pack(1),gcc使用__attribute(__packed__)(至少某些版本也支持#pragma pack語法)。

您也可以將record定義爲包含一些零字節作爲數據的一部分(例如,包含零終止符的字符串以使它們成爲字符串)。由於您未顯示record的定義,因此很難猜測這是否適用。

編輯:根據您的評論,似乎後者是這種情況。我要做的第一點是刪除這些可能不是一個好主意。如果你刪除它們,你必須做來讓程序讀取數據,知道一個字段結束和下一個字段開始(除非字段是固定寬度,可以隱式處理)。

最明顯的可能性是在每個字段前面加上其長度。這具有以下優點:如果/當您要查找文件時,您可以從一個字段到下一個字段而不讀取數據以查找終止字節。然而,通常情況下,我會使用一個索引 - 一個文件,其中包含文件偏移到數據中的連續記錄(可能還有每個記錄的一些關鍵數據,因此您可以根據記錄的內容快速搜索),所以您可以快速查找記錄的位置並讀取其數據。除非你有非常大的領域,尋求個別領域很少成就很多。

+0

正在寫個人會員是唯一的解決方案來獲得這個 –

+1

@Sachin Chourasiya:很多,是的。但是,通過使用'offsetof'來創建偏移量到字段開頭的數組,可以避免這麼麻煩,因此您可以將這些字段寫入循環中,而不是對'fwrite'進行100次單獨寫入的調用(或投入等)。請參閱:http://stackoverflow.com/questions/5088358/breaking-a-single-string-into-multiple-strings-c/5088496#5088496爲例。 –

+0

@Sachin:想象一下你可以把''\ 0''(和下面的字節)取出來。你如何確定下一位成員的開始? – pmg