2016-10-29 59 views
2

我正在嘗試計算從argv指定的文件中可能存在的行數和字符數。但是由於某種原因,當我點擊while循環時會出現分段錯誤。該程序運行良好,沒有while循環,但它只經過一次。我的while循環中的分段錯誤

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

int main(int argc, char *argv[]) { 

    if(argc != 2) { 
      return 0; 
    } 


    FILE *fp; 
    char c; 
    int lines = 0; 
    int chs = 0; 
    fp = fopen(argv[1], "r"); 

    //Segmentation Fault happens here on the while loop 
    while((c = fgetc(fp)) != EOF) { 
      if(c == '\n') { 
        lines += 1; 
      } 
      else { 
        chs += 1; 
      } 

    } 

    printf("Charaters: %d\n", chs); 
    printf("lines: %d\n", lines); 


    if(fp){ 
      fclose(fp); 
    } 
    return 0; 
} 
+3

如果'fopen()函數'進入循環前成功(!'FP = NULL')你有沒有檢查。將'NULL'指針傳遞給'fgetc()'會導致未定義的行爲。 – Peter

+1

'fgetc'有意返回一個'int'。 – Olaf

+0

問題是我打開一個空文件。所以我應該檢查一下它是否爲空。 – Sharpbombs

回答

2
  • 您的代碼必須遵循慣用C的緊密結合。
  • 您應該立即驗證fopen,而不是在您嘗試使用fp之後。
  • fgetc返回int而不是char。這是因爲它需要返回有關流的狀態的邊信道信息(即EOF),但該信息不能由char表示,但如果值不是EOF,則可以安全地將int值轉換爲char
  • \r\n代表換行符(而不僅僅是單獨的\n)時,您的代碼將\r視爲常規字符,您可能需要考慮如何處理不同的字符類。
  • 你的程序不處理非平凡的編碼(即它只能正確處理系統本地編碼中的文件,推測是ASCII)。您應該使用Unicode庫來正確讀取文件中的單個字符:例如,您的程序會將UTF-8中的代理對視爲兩個字符而不是1,並且會錯誤地計算UTF-16文件。

更好:

FILE* fp = fopen(argv[1], "r"); 
if(!fp) { 
    printf("Could not open file \"%s\" for reading.\r\n", argv[1]); 
    return 1; 
} 

int lines = 0; 
int chars = 0; 

int nc; 
while((nc = fgetc(fp)) != EOF) { 

    char c = (char)nc; 

    if  (c == '\n') lines++; 
    else if(c != '\r') chars++; 
} 

printf("Characters: %d\r\nLines: %d\r\n", chars, lines); 

fclose(fp); 

return 0;