2012-04-10 84 views
1

我正在製作出現在文件中的單詞的鏈接列表(不重複)以及它們首次出現的行。我完成了我認爲會很難的部分(解析文件的同時跟蹤行),但是我相信我現在在我的一個方法中遇到問題,我無法弄清楚如何解決。我的代碼有兩個文件,但我只在代碼中隨驅動程序一起包含帶有問題的方法。 (我嘗試使用GDB,我想我是用錯了,因爲它不停地說,它無法找到文件,它不會跑。)鏈接列表出現問題

int main(int argc, char **argv){ 
file = fopen(argv[1],"r"); 
/*struct fileIndex *fIndex = NULL;*/ /*put this in header file??*/ 
fIndex = NULL; 
delimiters = " .,;:!-";/*strtok chars to seperate*/ 
rewind(file); 
int buffer = 65; 
char str[buffer+1];/*where the lines are being stored*/ 
char *token, *cp; 
int i; 
int len; 
while((fgets(str, buffer, file))!=NULL){/*inserting lines*/ 
for(i=0; i<buffer; i++){ 
    if(str[i]=='\n'){ 
    str[i]= '\0'; 
    break; 
    } 
} 
len = strlen(str); 
cp = xerox(str); 
token = strtok(cp, delimiters); 
/*if(token!=NULL) 
printf("The word is %s\n", token);*/ 
    if(!present(fIndex, token)&&(token!=NULL)){ 
     insert(fIndex, i+1, token); 
    } 
    while(token!=NULL){ 
     token = strtok(NULL, delimiters); 
     /*if(token!=NULL) 
     printf("The word is %s\n", token);*/ 
     if(!present(fIndex, token)&&(token!=NULL)){ 
      insert(fIndex, i+1, token); 
     } 

    } 
} 
fclose(file); 
struct fileIndex *root; 
root = fIndex; 

while(root != NULL){ 
printf("The string is %s and on line %d\n", root -> str, root -> lineNum); 
root = root -> next; 
} 


free(fIndex); 
free(cp); 

return 0; 
} 







struct fileIndex *insert(struct fileIndex *head, int num, char *insert){ 
struct fileIndex* newnode = malloc(sizeof(struct fileIndex)); 
if(newnode==NULL) 
exit(1); 

newnode -> str = insert; 
newnode -> lineNum = num; 

newnode -> next = head; 
return newnode; 
} 

編輯:我還想到一個問題,我方法來檢查一個單詞是否已經存在或不存在。如果要插入單詞並打印所有單詞,我會在其中僅打印一個打印語句。最後打印列表的小循環不是打印,我認爲它在第一次到達時就達到NULL,並且從不循環。

present(struct fileIndex* fIndex, char *findIt){/*finds if word is in structure*/ 
struct fileIndex* current = fIndex; 
while(current!=NULL){ 
current = current -> next; 
if(strcmpigncase(current -> str, findIt)==0){ 
    return current -> lineNum; 
} 
} 
return 0; 
} 
+1

您看到了什麼問題? – 2012-04-10 01:10:35

回答

2

插入函數返回新的列表,但是您沒有在代碼中使用返回值。

的呼聲應該是這樣的:

fIndex = insert(fIndex, i+1, token); 

附錄:

此外,您使用您檢查之前,如果它是空令牌。它應該是這樣的:

if((token!=NULL) && !present(fIndex, token)){ 
    fIndex = insert(fIndex, i+1, token); 
} 
+0

我解決了這個問題,現在我得到了一個seg故障。 – Sams 2012-04-10 01:16:07

+1

你現在的函數是在while循環的頂部而不是在底部前進當前指針。 – 2012-04-10 01:17:54

+0

謝謝。我也意識到標題不正確!我忽略了返回值!應該解決我的一個邏輯問題。 – Sams 2012-04-10 01:22:41

2

你應該經常檢查fopen()是否成功。

if(file == NULL) { 
printf("Error fopen"); 
exit(1); 
} 

fgets()追加空終止,所以您不必自己做。

0
file = fopen(argv[1],"r"); 

您忘記檢查fopen()是否成功。每個fopen(3)應遵循類似的代碼:(?回落到默認值)

if (!file) { 
    fprintf(stderr, "unable to open %s\n", argv[1]); 
    perror(argv[0]); 
    exit(EXIT_FAILURE); 
} 

如果可以更加妥善地處理錯誤不是退出,那麼你可能想這樣做。

for(i=0; i<buffer; i++){ 
    if(str[i]=='\n'){ 
    str[i]= '\0'; 
    break; 
    } 

這很醜陋。你不需要用空字符結束自己,但如果你想刪除的換行符,那麼你也應該確保你正在計算新行你行號...

struct fileIndex *root; 
root = fIndex; 

while(root != NULL){ 
    printf("The string is %s and on line %d\n", root -> str, root -> lineNum); 
    root = root -> next; 
} 


free(fIndex); 
free(cp); 

我從來沒有真正看到fIndex分配 - 它只是一個指針,並且你在開始時指定它爲NULL。整段代碼看起來都很貼切,缺乏正確的縮進和周圍的上下文使得幾乎不可能理解。我必須認爲,你應該將所有這些代碼分離到他們自己的例程中,使用硬編碼測試徹底地測試它們,並且在試圖將它連接到更大的程序之前確保它完美地工作。 (這實際上也適用於第一部分 - 它看起來會受益於一些獨立的定向測試。)

+0

我試圖測試它實際上是用打印循環做出列表。 – Sams 2012-04-10 01:25:09