2017-10-08 76 views
0

我正在開發一個C函數,用於對給定鍵周圍的文本進行排序。 比方說,你有以下文件:C排序程序中的分段錯誤

this line is first 
but this line is second 
finally there is this line 

如果你運行該程序,並給它這個文件作爲輸入,它應該打印:

but this line is second 
finally there is this line 
this line is first 

因爲不過是字母前最後是在此之前。

但是,如果您傳遞一個標誌來對不同的鍵進行排序,則會得到不同的輸出。例如,如果你調用fastsort -2這個文件,你應該得到:

this line is first 
finally there is this line 
but this line is second 

,因爲全系標配在此之前有到來之前。是的,我假設-2代表每行中的第二個單詞(與大多數人一樣,除了計算機科學家總是希望從0開始)。此外,如果指定的鍵不存在於輸入文件的特定行上,我應該只使用該行的最後一個詞作爲鍵。例如,如果用戶想要對第4個單詞(-4)進行排序,並且排序遇到類似此行的線(採樣線),則排序應使用單詞對該行進行排序。

我的問題來自於最後一個假設,我使用strtok()來提取鍵給出的單詞,但是如果鍵大於該行中的單詞數,則會出現分段錯誤。這是函數的主體;

typedef struct { 
    char word[128]; 
    int index; 
} wordIndex; 

char** fastsort(char** text, int word){ 

char** sortedText; 
char* LineAux; 
int i; 
wordIndex tokenLines[numLines]; 

for(i=0; i<numLines; i++){ 
    char* token; 
    int j = 0; //counter 

    LineAux = (char*) malloc(MAX_LENGTH*sizeof(char)); //MAX_LENGTH = 128 
    if (LineAux==NULL){ 
     fprintf(stderr,"Error, malloc failed"); 
     exit(1); 
    } 

    strcpy(LineAux,text[i]); 

    token = strtok(LineAux, " \n"); 
    j++; 

    if(token == NULL){ //if blank line 
     token=" "; 

    } else { 

     while(token != NULL){ //segmentation fault 
      if(j == word){ 
       break; 
      } 
      token = strtok(NULL, " \n"); 
      j++; 

     } 
    } 

    strcpy(tokenLines[i].word,token); 
    tokenLines[i].index=i; 
    free(LineAux); //free Aux string 
    printf("token: %s Line: %d \n",tokenLines[i].word, tokenLines[i].index); 
} 

qsort(tokenLines,numLines,sizeof(wordIndex),compareTo); //sorting tokens 

sortedText = (char**) malloc(numLines*sizeof(char*)); 
if (sortedText==NULL){ 
    fprintf(stderr,"Error, malloc failed"); 
    exit(1); 
} 


//reordering text 
int n; 
for (n=0; n<numLines; n++){ 
    int index; 

    sortedText[n]=(char*) malloc(MAX_LENGHT*sizeof(char)); 

    if (sortedText[n]==NULL){ 
     fprintf(stderr,"Error, malloc failed"); 
     exit(1); 
    } 

    index = tokenLines[n].index; 
    strcpy(sortedText[n],text[index]); 

} 


return sortedText; 

}

分段錯誤出現的while循環中。 希望你能幫忙,謝謝你提前。

+0

'text [i]'可以長於127個字符加終止字節嗎?因爲如果可以的話,你的'strcpy'會超出'LineAux'的範圍。 'text [index]'進一步向下。 –

+0

@CharlesSrstka不,我有另一個功能(從文件中提取文本),防止行超過127個字符(+終止),所以它永遠不會比這更長 – Setekorrales

+0

什麼是'wordIndex'?某種結構我採取它? –

回答

1

我在我的機器上運行了上面的代碼。它的工作,一個警告; word是1索引,而不是像你所期望的0,因爲j在與任何事物比較之前都會增加。所以,如果你輸入0,你自然不會,如果你想用的第一個詞進行排序,這條線是永遠不會是真實的:

if(j == word){ 

因此,while循環繼續,直到令牌NULL。然後,在循環後,您strcpy崩潰,因爲它試圖尊重你傳遞給它的空指針:

strcpy(tokenLines[i].word,token); // don't NULL me bro! 

這是你的崩潰的根源。爲了解決這個問題,我會想辦法讓兩個轉變:

  1. 得到循環之前擺脫j++的。讓索引開始於0,因爲這通常是在C中完成的以及函數的用戶通常期望的內容。

  2. 循環結束後,測試token以查看它是否爲NULL。如果是,優雅地退出該功能,可能會向用戶返回某種錯誤。如果有人輸入一個無效的單詞編號就會崩潰,這是糟糕的UI。

0

Allrigth,我有解決辦法;

問題是while循環內部指令的順序。

這裏是工作的解決方案:

/** 
* Function that sorts text by a given key 
* @param text: array of strings which is going to be sorted 
* @param word: key where the sort starts 
* @return sorted text 
*/ 
char** fastsort(char** text, int word){ 

    char** sortedText; 
    char* LineAux; 
    int i; 
    wordIndex tokenLines[numLines]; 

    for(i=0; i<numLines; i++){ 
     char* token; 
     int j = 0; //counter 

     LineAux = (char*) malloc(MAX_LENGHT*sizeof(char)); 
     if (LineAux==NULL){ 
      fprintf(stderr,"Error, malloc failed"); 
      exit(1); 
     } 

     strcpy(LineAux,text[i]); 

     token = strtok(LineAux, " \n"); 
     j++; 

     if(token == NULL){ //if blank line 
      token=" "; 

     } else { 

      while(token != NULL){ //segmentation fault 
       strcpy(tokenLines[i].word,token); 
       if(j == word){ 
        break; 
       } 

       token = strtok(NULL, " \n"); 
       j++; 

      } 
     } 

     tokenLines[i].index=i; 
     free(LineAux); //free Aux string 
    } 

正如你所看到的,變化不是很有效,但它的工作,現在,如果你有一個替代的解決方案,我會很樂意去嘗試。