2010-08-09 120 views
0

問題是查找並替換C文件中的字符串在C文件中查找並替換

我是C文件新手。我曾嘗試下面的代碼,但我沒有得到任何輸出:

#include<stdio.h> 
    #include<string.h> 
    int main() 
    { 
     FILE *f1,*f2; 
     char *src,*dest,*s1,ch,ch1,ch2,ch3; 
     int i; 
     f1=fopen("input.txt","rw"); 
     f2=fopen("dummy.txt","rw"); 
     src="mor"; 
     dest="even"; 
     while(ch!=EOF) 
     { 
     ch=fgetc(f1); 
     if(ch==src[0])      //Finding 1st char of src 
     { 
     fgets(s1,strlen(src),f1); 
     if(strcmp(src+1,s1)==0)   //Finding occurance of "src" in file 
     { 
      fseek(f1,strlen(src)-1,SEEK_CUR); 
      while(ch1!=EOF)    //Copying remaining data into another file 
      { 
      ch1=fgetc(f1); 
      fputc(ch1,f2); 
      } 
     fseek(f1,-strlen(src),SEEK_CUR); 
     for(i=0;i<strlen(dest);i++) //replacing "src" with "dest" 
     { 
      ch2=dest[i]; 
      fputc(ch2,f1); 
     } 
     fclose(f1); 
     f1=fopen("input.txt","a"); 
     while(ch3!=EOF)  //Appending previosly copied data into 1st file 
     { 
      ch3=fgetc(f2); 
      fputc(ch3,f1); 
     } 
    } 
    } 
} 
    fclose(f1); 
    fclose(f2); 
} 

input.txt中的內容是「早晨」。

請指出邏輯中的錯誤,並給出相同的有效代碼。

在此先感謝。

+2

最明顯有效的代碼會是這樣的:'sed的 「S /源/目標/ G」 input.txt'。直接用C做這件事並沒有什麼意義(至少在我看來)。 – 2010-08-09 15:14:28

+2

@Jerry Coffin ...先生,但問題是要測試我們對使用C文件的理解! – 2010-08-09 15:21:52

+0

「這個問題被要求測試我們對使用C文件的理解」 - 這是一個家庭作業問題嗎?如果是這樣,您可能需要添加「作業」標籤。 – 2010-08-10 05:38:04

回答

3

在C中讀取文件通常有點混亂。我看到的第一個問題是ch在主循環中的使用方式。第一次執行

while (ch != EOF) 

,CH是未初始化的,如果碰巧持有EOF,主循環將根本不執行。我通常用以下結構從文件中讀取:

FILE *fInput = fopen("input.txt", "r"); 
int ch; /* need an int to hold EOF */ 

for (;;) 
{ 
    ch = fgetc(fInput); 
    if (ch == EOF) break; 

    ... 
} 

另外,你可能需要在文件指針的概念讀了。例如,在讀取src的其餘部分後,您將fseek()轉發,並在將數據複製到f2之前跳過更多字符。本質上,你讀m,讀or(與fgets() - 並進入一個未分配的緩衝區s1,這將在不久的將來有一段時間ka-boom),再跳過2個字符(現在你的指針是在「早晨」 ),將「ng」複製到f2中,嘗試在此循環中將EOF寫入f2(因此上述讀取模式直到EOF),尋找兩個字符(一旦達到EOF就可能失敗,我的C文件功能有點生鏽這些日子)​​,寫「甚至」到f1(如果我在EOF之後尋找錯誤,請將輸入文件設置爲「mornieven」,並且如果我正確的話不要更改它)。總之,我認爲代碼不會做你打算做的事情。

我會建議建立你的功能。下面的每一個可以寫成你應該纔去下一步測試和完成的程序:

  1. 讀取安全文件,並打印出來
  2. 檢測src內容,並打印輸入
  3. 的其餘部分保存輸入到第二個文件,其餘的不是打印
  4. 在第一文件dest替換src,而忽略其他(因爲你打開輸入文件「RW」,這將截斷的休息輸入)。您可能需要執行fseek()來清除EOF狀態。另外,也要看看ftell()記錄,你可以跳回到使用fseek()
  5. 最後一個位置,複製一切,你有dest(無需更換src在這裏收F1後保存到第二個文件,但最好是打開F2作爲寫入,從第一個文件複製後關閉,然後重新打開以執行復制回f1)。

此外,當你需要一個緩衝(如S1),只需使用一個足夠大的數組了,但考慮malloc()free()函數來執行動態內存分配這樣的情形。

+0

非常感謝您分析整件事的努力。我不能夠感謝你。在找到「src」後,我使用了fseek,我不知道fgets移動文件指針。我應該更好地閱讀這些概念。所以,如果這件事情得到照顧,該程序做我打算做的對嗎? 我也會嘗試U給的方法......再次感謝!!!! – 2010-08-10 15:00:51

1

您在輸出中打印錯誤的東西。打印「ch」,而不是文件指針。

 
while(ch!=EOF) 
{ 
    ch=getc(f1); 
    printf("%c",ch); 
} 
while(ch!=EOF) 
{ 
    ch=getc(f2); 
    printf("%c",ch); 
} 

此外,f2在輸出過程結束時關閉。你將不得不重新打開它(就像你與F1做的。)

+0

@Starsky,我有你的點先生。我在代碼中改變了它。 我已經刪除了打印部分。 請檢查替換邏輯中的任何錯誤先生。該input.txt的文件將不會得到改變上運行,並且原始內容將保留....感謝烏拉圭回合的幫助爵士...... – 2010-08-09 15:24:08

2

一種簡單的方法做替代將是在整個文件中第一次讀入緩衝區

例如

FILE* fpIn = fopen("file.txt","rb"); 
fseek(fpIn, 0L, SEEK_END); 
size_t s = ftell(fpIn); 
fseek(fpIn, 0L, SEEK_SET); 
void* buf = malloc(s); 
fread(buf,s,1,fpIn); 

現在在寫文件,檢查您的字符串

char src[] = "mor"; 
char dest[] = "even"; 
int lenSrc = strlen(src); 
int lenDest = strlen(dest); 
for (char* ch = buf; ch < buf + s; ++ch) 
{ 
    if (!memcmp(ch, src, lenSrc)) 
    { 
    fwrite(dest, 1,lenDest, fpOut); 
    ch += lenSrc; 
    } 
    else 
    { 
    fputc(*ch, fp); 
    } 
} 

免責聲明:沒有編制本

+0

@Andres K,非常感謝先生......我會盡力ü給先生的方法,我認爲這比搜索和替換文件更容易! – 2010-08-10 15:03:11

1

乍一看,我看你的代碼中調用與fgets是錯誤的。您尚未分配任何內存,並且正在將字符串讀入未初始化的指針。讀入數組或動態分配的內存。

+0

就像你指出的,fgets似乎沒有問題。它編譯罰款和執行正確..我將其讀入其中previosly宣佈..... – 2010-08-09 15:45:35

+1

@Shyam你的'fgets'是不正確的字符串。 's1'不是一個字符串,它是一個指向字符數組的指針,它是未經過初始化的。您正在寫入未分配的內存。這不是編譯錯誤;這是一個更嚴重的邏輯錯誤,會導致未定義的行爲。 – meagar 2010-08-09 17:00:30

+0

@meager .... s1未初始化,邏輯上它不正確..我知道tat。但由於我沒有得到任何的錯誤,所以我會保持原樣。能否檢查我在程序中使用的邏輯中的任何錯誤。 Thnaks – 2010-08-10 14:52:30

1

另一個問題是,您聲明chcharfgetc()返回int,並有很好的理由。這是好事,可以返回任何可能的字符或EOF,所以EOF不應該是一個角色,所以理想fgetc()返回比char更大的類型。

結果是循環可能永遠不會結束,因爲ch在某些標準實現上不可能保存EOF。聲明它(ch1ch3)爲int