2015-11-19 26 views
0
int ch; 
char Name1[24], Name2[24],*p1,*p2; 
while ((ch = fgetc(inz)) != EOF){ 

      fseek(inz, -1, SEEK_CUR); 

     fgets(Name1, 24, inz); 
     fgets(Name2, 24, inz); 
     p1 = Name1; 
     p2 = Name2; 
     p1 += 3; 
     p2 += 3; 

     if (atoi(p1) > atoi(p2)){ 
      fseek(inz, -46, SEEK_CUR);    
      fputs(Name2, inz);    
      fputs(Name1, inz);    

     } 
     fseek(inz, -23, SEEK_CUR);  
     i --; 
    } 

我有這段代碼。 inz是我在r + mod中的文件。我想將每個字符串與下一個字符串進行比較,並根據第4個字符對它們進行排序。該功能正在工作,但..它不可阻擋它永遠運行... **我試圖改變int ch;也是焦點。仍然沒有工作,feof沒有工作。fgetc不停止我的循環

+0

「我」在哪裏定義以及它在做什麼?我認爲你永遠不會到達EOF,因爲你反覆調用fseek來倒帶文件。我建議開始在另一個文件中編寫有序列表。 –

+0

在循環的每次迭代中,在讀入('ch','Name1','Name2','p1'和'p2')後打印出所有變量。此外,打印'ftell()'的結果,以便您可以看到文件中的位置。這應該能讓你明白你的邏輯錯誤。 – dbush

+0

請在文件樣本的預期變更後提交文件。 – BLUEPIXY

回答

1

有幾個問題與您的代碼:

1)你正在做的假設,即每行至少4個字符長(加換行符)。如果該行小於4個字節,則不會基於字符串本身進行排序,而可能是基於未初始化的內存進行排序。

2)你說過要根據第4個字符比較每一行,但實際上是根據從第4個字符開始的字符串進行比較。您將它轉換爲整數,這意味着您還假設該行包含數字值。

3)假設每個字符串在文件中佔用了24個字節。我想你假設每個字符串都是23個字符加一個換行符?這個假設是否有效?如果線可以短於24個字節那麼這段代碼是不正確:

fseek(inz, -46, SEEK_CUR);    

相反,你要回滾到兩個字符串加上兩個新行的實際總長度。即使字符串是23字節,你也不會考慮這裏的換行符,所以你想要倒帶-48不是-46。

4)將字符串寫回文件時,您使用的fputs不包含換行符。

5)你並沒有真正對文件進行排序,你只是經歷了一次泡泡排序的迭代。您將根據比較重新排序當前的兩行,但不會對整個文件進行排序。所以這種邏輯也是錯誤的。

閱讀每一行,將其粘貼在一個數組中,根據您提到的標準對數組進行排序,然後將其寫回文件會更清晰。

因此,除此之外,爲什麼循環永遠不會結束?

在循環中的最後一行是這樣的:

fseek(inz, -23, SEEK_CUR); 

這意味着總是追溯到23個字節只是試圖讓下一個字符(龜etc)前。那麼你永遠不會看到EOF。

0

那麼,如果你做了一個fgets,你將只能得到一個EOF文件指針已經在文件末尾。並且在您測試返回值的唯一fgetc之前的說明是fseek(inz, -23, SEEK_CUR);

這意味着當您到達文件結尾時,首先返回23個字節,成功讀取某些內容,並且可能會在忽略返回值的以下兩個fgets中的任何一個上獲得EOF。並永遠重複...

你應該怎麼做?至少測試每一個返回值讀取功能:

if (fgets(Name1, 24, inz) == NULL) break; 
    if (fgets(Name2, 24, inz) == NULL) break; 

但它不是全部。除非你是真的確定你的所有行總是隻有23個字符,並且文件以二進制模式打開(或者你在Linux上),所以從不使用這種fseek。唯一合理的方法是將位置ftell然後fseek存儲到該位置。

最後但並非最不重要的一點,你的algorythm回去一行,在Name1中讀取你剛剛在Name2中讀到的內容。而應該換P1和P2,總是讀入P2和比較P1和P2

這其中將整理文件無論是線尺寸提供他們都比尺寸比4短,但長:

size_t oldpos = 0, tmp; 
char Name1[SIZE], Name2[SIZE],*p1,*p2; 
p1 = Name1; 
p2 = Name2; 
/* read first line and note position after it */ 
if (fgets(p1, SIZE, inz) == NULL) return; 
tmp = ftell(inz); 
/* loop reading in p2 */ 
while (fgets(p2, SIZE, inz) != NULL){ 

    if (atoi(p1 + 3) > atoi(p2 + 3)){ 
     /* swap last two lines */ 
     fseek(inz, oldpos, SEEK_SET);    
     fputs(p2, inz); 
     fputs(p1, inz);   
     /* and go back to beginning of file - not optimal but robust */  
     fseek(inz, 0, SEEK_SET); 
     /* again last line in p1 and note position */ 
     fgets(p1, SIZE, inz); 
     oldpos = 0; 
     tmp = ftell(inz); 
    } 
    else { 
     /* order is ok untill here, note new position and swap buffers */ 
     oldpos = tmp; 
     tmp = ftell(inz); 
     swap(&p1, &p2); 
    } 
}