2013-04-09 72 views
1

我正在嘗試計算文件中每個字的數量。該文件可以是stdin或命令行中提供的文件名(./ count -f)。到目前爲止,程序在從命令行讀取文件時會提供正確的輸出。但是當我試圖從標準輸入讀取時發生錯誤。程序首先輸出正確,然後給出分段錯誤(核心轉儲)。這是我的代碼的一部分。從標準輸入讀取的分段錯誤(核心轉儲)

FILE * fp; 
int size = 20000; 
char sentence[2000]; // the sentence from stdin 
if (argc != 3) 
{ 
    fgets(sentence,sizeof(sentence),stdin); // read from stdin 
    fflush(stdin); 
    // I think the initialization of word is incorrect, but i do know why it is incorrect 
    char *word = strtok (sentence," !\"#$%&'()*+,./:;<=>[email protected][\\]^_`{|}~\n\t"); 
    while (word != NULL) 
    { 
     get_word(word); // get each word 
     word = strtok (NULL, " !\"#$%&'()*+,./:;<=>[email protected][\\]^_`{|}~\n\t"); 
    } 
} 
else 
{ 
    fp = fopen(argv[2], "r"); 
    if (fp == 0) 
    { 
     printf("Could not open file\n"); 
    } 

      char word[1000]; 
    while (readFile(fp, word, size)) { // let the program read the file 
     get_word(word); // get each word. Works well. 
    } 
} 

get_word功能:

void get_word(char *word){ 
node *ptr = NULL; 
node *last = NULL; 

if(first == NULL){ 
    first = add_to_list(word); // add to linked list 
    return; 
} 

ptr = first; 
while(ptr != NULL){ 
    if(strcmp(word, ptr->str) == 0){ 
     ++ptr->freq; 
     return; 
    } 
    last = ptr;    
    ptr = ptr->next; 
} 
last->next = add_to_list(word); // add to linked list 

}

請幫我弄清楚,爲什麼我得到一個分段錯誤(核心轉儲)。該程序適用於我的Mac,但不適用於Linux。
在此先感謝。

+0

'fflush(stdin)'觸發未定義的行爲。 get_word是做什麼的? – cnicutar 2013-04-09 19:07:20

+0

這不是根本原因,但你不應該調用'fflush(stdin);' - 輸入流中未定義fflush。 – Joe 2013-04-09 19:07:49

+0

不,它不是fflush(stdin)問題。我刪除它,但仍然得到錯誤。我認爲這是一個記憶問題。該程序適用於我的Mac,但不適用於Linux。 – user605947 2013-04-09 19:11:22

回答

0

問題是

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

    if (argc != 3) 
    { 
      fgets(sentence,sizeof(sentence),stdin); 
      // and so on 
    } 
    else 
    { 
      fp = fopen(argv[2], "r"); 
      if (fp == 0) 
      { 
        printf("Could not open file\n"); 
      } 
      while (readFile(fp, word, size)) { 
        get_word(word); 
      } 
    } 

    // do some stuff, sorting etc. 

    fclose(fp); 

fclose(fp)無論它是否被打開了。如果fp沒有連接到有效的流,則分段錯誤很常見。很顯然,有些實現會優雅地處理fcloseNULL參數,這就是它在Mac上工作的原因。

移動電話fclose進入else分支,而當fopen失敗,不只是

printf("Could not open file\n"); 

,但最終的方案。

+0

非常感謝Daniel。大幫助。對此,我真的非常感激。 – user605947 2013-04-09 20:11:46

+0

不客氣。幫助(和有趣的謎題)就是我來這裏的原因。 – 2013-04-09 20:12:58

0

句子大小是2 kib,而你正在讀取stdin的2 kib。之後你使用一個字符串函數。字符串以'\ 0'結尾,但由於您讀取了2個沒有'\ 0'的kib數據,因此沒有字符串結束,所以它是段錯誤,因爲字符串函數(在這種情況下爲strtok)可能工作遠遠超過2親屬。

+0

'fgets' 0-終止它讀取的數據。 – 2013-04-09 19:12:38

+0

我只用一個字符測試過它。 – user605947 2013-04-09 19:14:51