2010-07-16 96 views
1

當新項目添加到文件時,頁腳應更新當前時間和小時。 下面是示例文件格式,將項目添加到文件的最後一行之前的文件中

ITEM1
ITEM2
06/07/2010 10時二十○分22秒 //頁腳行

的「項目」具有現有文件中追加,在頁腳行之前,頁腳應該更新爲新值。 我不得不把變量,「項目」和「時間」作爲字符串保持各自的價值觀。

加入新的項目(ITEM3)的文件看起來像後,

ITEM1
ITEM2
ITEM3
07/07/2010十七點20分十二秒 //改變頁腳

幫助我實現這一目標。

回答

3

由於頁腳行是靜態長度...

尋求到頁腳行的開頭,寫上新的項目在它跟着一個換行符,然後寫出來的新註腳。

(注意,此過程是危險的,如果你不能保證,你將永遠寫至少足夠的總字節覆蓋現有的頁腳,但它看起來像你正是這樣保證在這裏。)

+0

良好的靜態長度調用(假設它是,我認爲它不是),+1。 – falstro 2010-07-16 07:54:30

+0

你可以請一個樣本片段尋求部分? – arun 2010-07-16 08:40:31

+0

@arun; 'char footer [] =「00/00/0000 00:00:00 \ n」; FILE * f = fopen(「myfile」,「a +」); fseek( - (sizeof(footer)-1),SEEK_CUR)); fprintf(f,「我的下一個項目\ n」); fwrite(footer,1,sizeof(footer)-1,f); fclose(f);'sizeof上的-1是爲了移除字符串文字中的隱式空終止。 – falstro 2010-07-16 09:35:56

3

我解決方案是,fopen模式「r +」(讀寫)。 fseek從最後開始,緩衝區長度值並填充它(再次將光標放在末尾),向後搜索緩衝區以獲取最後一個換行符(如果沒有,則搜索甚至進一步返回並重復),一旦找到(或者你打到文件的開頭),搜索文件中的那個位置(你的閱讀將它放在其他地方),然後寫下你的新項目,然後是一個新行,然後是一個新的頁腳。關閉該文件,並將其尺寸設置爲合適的尺寸truncate

HTH。

編輯:
如果頁腳始終是相同的大小,我肯定去尼古拉斯解決方案。

+0

謝謝。由於它是靜態長度頁腳,我會嘗試與尼古拉斯解決方案:) – arun 2010-07-16 08:42:53

+0

你能否給我提供一個fseek的樣本片段?謝謝。 – arun 2010-07-16 09:18:35

+1

我不認爲'a +'是正確的。正如[指出](http://stackoverflow.com/questions/3264495/appending-a-data-to-file-in-c/3264542#3264542)bluesmoon,它應該是'r +'。 [docs](http://www.opengroup.org/onlinepubs/009695399/functions/fopen.html)表示,任何以'a'開頭的模式都會導致所有寫入被強制結束,而不管搜索結果如何。 – 2010-07-16 12:07:13

0

一個簡單的(但不是很有效)算法看起來是這樣的:

string content = ""; 
string line = ""; 

// Append every but the last line to content 
while(!eof(file)) 
{ 
    content += line; 
    line = readline(file); 
} 

content += getNewItem(); 
content += generateFooter(); 

save(content); 
+0

謝謝。實際文件太大,我可能會面臨緩衝區問題或效率低下,如你所說:) – arun 2010-07-16 09:21:57

0

這是很容易。您只需截斷最後一行。

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

#define NEWLINE "new line to append\n" 

int main() { 
    FILE *file; 
    char *line = NULL; 
    size_t previous_line_offset = 0, line_offset = 0; 
    time_t time_signature; 

    // open data file 
    if((file = fopen("data.txt", "rw+")) == NULL) { 
    puts("ERROR: Cannot open the file"); 
    return 1; 
    } 

    // find last line offset 
    while(!feof(file)) { 
    int n; 
    previous_line_offset = line_offset; 
    line_offset = ftell(file); 
    getline(&line, &n, file); // NOTE getline is a GNU extension 
    } 

    // append new line 
    fseek(file, previous_line_offset, SEEK_SET); 
    fputs(NEWLINE, file); 

    // apend signature 
    time(&time_signature); 
    fprintf(file, "%s", asctime(localtime(&time_signature))); 

    // free resources 
    fclose(file); 
    if(line) 
    free(line); 

    // voila! 
    return 0; 
} 
+0

謝謝。我在哪裏可以得到getline()? – arun 2010-07-16 08:56:59

+0

getline是一個GNU擴展。它僅在GNU libc庫中可用。在Visual Studio上,你可以使用std :: getline(但它是C++)。 – 2010-07-16 09:03:56

+0

您是否有其他解決方案不使用任何其他擴展? 謝謝。 – arun 2010-07-16 09:17:22

1

在類似的說明中;無論何時修改文件,文件元數據都會更改以更新上次寫入文件的確切時間。您始終可以在Windows上使用GetFileTime()查詢該數據。

相關問題