2013-07-20 28 views
1

C新手,我試圖做一個文本替換到位。我認爲fopen中的r +應該允許我讀寫。我正在查看文件中的每一行,如果它以/開始,那麼我預先將http://example.com添加到該行的開頭。示例...行是/ tree,那麼該行將變爲http://example.com/tree。正則表達式工作正常。我可以很好的閱讀這個文件,但它並沒有寫入。任何想法爲什麼?讀寫地方不寫?

void 
fix_relative (char *page) 
{ 
    FILE *fp; 
    fp = fopen ("file", "r+"); 

    char line[1000]; 
    regex_t re; 
    regcomp (&re, "^/", REG_EXTENDED); 

    while (fgets (line, sizeof line, fp) != NULL) 
    { 
     if (regexec (&re, line, 0, NULL, 0) == 0) { 
    fprintf (fp, "http://example.com%s\n", line); 
     } 
    } 

    fclose (fp); 
} 
+1

使用ftell()和fseek()返回更多。 –

+0

你真的必須在c中做這個嗎? 'sed -i's | ^/| http://example.com/ |'文件' – Kevin

+0

@凱文 - 有效的點,但我想我應該知道爲什麼這不起作用。 – user983223

回答

2

沒有辦法,這可能會工作。只要原始字符串與新字符串完全相同,就會遇到問題。此外,由於您正在使用文本模式,因此可能會因爲換行/回車換行而出現其他人爲因素。

相反,做到以下幾點:

  • 打開文件「文件」只讀
  • 創建一個新的臨時文件,寫入只有
  • 讀取一行,如果有必要修改,寫入新文件
  • 完成後,刪除「文件」並重命名您的臨時文件。
2

這可以幫助你瞭解你的問題

fopen函數

目的: 打開流。更安全的fopen_s功能也可用。

語法: FILE * fopen(const char * name,const char * mode);

聲明中:

函數fopen打開,其名稱是字符串按名稱指向的文件和流與它關聯。該字符串可能包含完整路徑(來自根目錄),相對路徑(來自當前目錄)或僅包含名稱。

參數模式指向一個字符串。如果字符串是下列之一,則文件在指定的模式下打開。

  • 「r」打開文本文件進行閱讀。
  • 「w」截斷零長度或創建文本文件進行寫入。
  • 「a」追加;打開或創建用於在文件結尾寫入的文本文件。
  • 「rb」打開二進制文件進行閱讀。
  • 「wb」截斷零長度或創建用於寫入的二進制文件。
  • 「ab」追加;打開或創建用於在文件結尾寫入的二進制文件。
  • 「r +」打開文本文件進行更新(讀取和寫入)。
  • 「w +」截斷零長度或創建更新文本文件。
  • 「a +」追加;打開或創建文本文件進行更新,寫在文件結尾。
  • 「rb +」打開二進制文件進行更新(讀取和寫入)。
  • 「wb +」截斷零長度或創建二進制文件進行更新。
  • 「ab +」追加;打開或創建二進制文件進行更新,寫入文件結尾。
  • 「R + B」 等同於 「RB +」
  • 「W + B」 等同於 「WB +」
  • 「A + B」 等同於 「AB +」

打開具有讀一個文件模式('r'作爲mode參數中的第一個字符)如果文件不存在或無法讀取,則會失敗。

用追加模式('a'作爲mode參數中的第一個字符)打開文件會導致文件的所有後續寫入被強制爲當前的文件結束,而不管中介對fseek的調用功能。

當一個文件被打開與更新模式(「+」作爲模式參數的第二個或第三個字符),輸入和輸出可在相關聯的流來執行。然而,輸出不應直接跟隨輸入,而不需要對fflush函數或文件定位函數(fseek,fsetpos或rewind)進行干預調用,並且輸入不應直接跟隨輸出,而不需要中間調用文件定位函數,除非輸入操作遇到文件結束。

打開時,如果只有一個流可以確定不引用交互式設備,則該流完全緩衝。流的錯誤和文件結束指示符被清除。

返回: 指向成功控制流的對象的指針,否則爲空指針。

1

一兩件事,可能不是很清楚:如果更新文件中的行,和你的置換文本不被正是相同的長度因爲它是什麼代替,你會做該文件的完整哈希:你會覆蓋後面的內容。

所以,如果你有一個包含句子文件:

I love programming. 
    I love life. 

並設置文件位置的第一句話與「厭惡」代替「愛」,你不會得到

I loathe programming 
    I love life 

你會得到

I loathe programming love life 

,因爲你現在已經覆蓋從行分隔符第一句和下一句的「I」。

如果用較長的字符串替換字符串,則會將文件中的每個其他字符向前推。要做這個替換,你必須把整個文件讀入內存,做替換,然後把文件寫回磁盤。

+0

我剛剛發現了這個!這並不好玩。 – user983223