2013-10-14 54 views
0

我试图读取文本文件并将其中的字符串逐字地添加到链接列表中。我对C相当陌生,不太了解指针。我遇到了几个不同的错误,但是现在我的插入方法出现了分段错误。这实际上很令人沮丧。有人能解释我在这里做错了吗?将文本文件读入链接列表

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

struct listNode { /* self-referential structure */ 
    char data[50]; 
    struct listNode *nextPtr; 
}; 

typedef struct listNode LISTNODE; 
typedef LISTNODE *LISTNODEPTR; 

void insert(LISTNODEPTR *, char[]); 
void printList(LISTNODEPTR); 
char fpeek(FILE *); 

main() { 

    FILE *fptr; 
    char file_name[20]; 
    int nrchar = 0; 
    LISTNODEPTR startPtr = (struct listNode *) malloc(sizeof(struct listNode)); 
    char word[50]; 
    char c; 
    int i; 

    printf("What is the name of the file in which the text is stored?\n"); 
    scanf("%s",file_name); 
    // printf("Type the number of characters per line"); 
    //scanf("%d", &nrchar); 
    fptr = fopen(file_name,"r"); 
     while(fpeek(fptr) != EOF) { 
     i = 0; 
     while(fpeek(fptr) != ' '){ 
     word[i] = fgetc(fptr); 
     i++; 
     printf("%d", i); 
     } 
     word[strlen(word)] = '\0'; 
     insert(&startPtr, word); 
     word[0] = '\0'; 
    } 
    fclose(fptr); 
    printList(startPtr); 


return 0; 
} 

    /* Insert a new value into the list in sorted order */ 
    void insert(LISTNODEPTR *sPtr, char value[]) 
    { 
     LISTNODEPTR newPtr, currentPtr; 

     newPtr = malloc(sizeof(LISTNODE)); 
     strcpy(newPtr->data, value); 
     newPtr->nextPtr = NULL; 
     currentPtr = *sPtr; 

     while(currentPtr != NULL){ 
     currentPtr = currentPtr->nextPtr; 
     } 
     currentPtr->nextPtr = newPtr; 

    } 


    /* Return 1 if the list is empty, 0 otherwise */ 
    int isEmpty(LISTNODEPTR sPtr) 
    { 
     return sPtr == NULL; 
    } 

    /* Print the list */ 
    void printList(LISTNODEPTR currentPtr) 
    { 
     if (currentPtr == NULL) 
      printf("List is empty.\n\n"); 
     else { 
      printf("The list is:\n"); 

      while (currentPtr != NULL) { 
      printf("%s --> ", currentPtr->data); 
      currentPtr = currentPtr->nextPtr; 
      } 

      printf("EOF\n\n"); 
     } 
    } 

    char fpeek(FILE *stream) { 
     char c; 
     c = fgetc(stream); 
     ungetc(c, stream); 
     return c; 
    } 

回答

3

首先,从库函数检查返回值像fopen()函数等

其次,看simonc的答案。

三,本次循环之后:

while(currentPtr != NULL){ 
    currentPtr = currentPtr->nextPtr; 
    } 
    currentPtr->nextPtr = newPtr; 

currentPtr为空,所以currentPtr->nextPtr = newPtr;将间接引用一个空指针。 也许类似

while(currentPtr && currentPtr->nextPtr) { 
    currentPtr = currentPtr->nextPtr; 
    } 
    currentPtr->nextPtr = newPtr; 

更多的是你在找什么。

最后,

​​

应该

int fpeek(FILE *stream) { 
    int c; 
    c = fgetc(stream); 
    ungetc(c, stream); 
    return c; 
} 

,并在主

char fpeek(FILE *); 

应该

int fpeek(FILE *); 
+0

我做了更改并且段错误消失了,但是现在我认为我在某处发生了无限循环。另外,你是什么意思通过检查库函数的返回值? – user2880410

+0

您应该检查fopen()的返回值以查看它是否为null。在这种情况下,它看起来不是这样,但它是很好的编码风格。至于循环,我不确定,你的嵌套fpeek()循环很难遵循。 –

+0

这个单词[strlen(word)] ='\ 0';'应该是'word [i] ='\ 0'; –

0

我刚刚看了一下你的代码,我敢肯定的段错误的问题是在这里:

while(currentPtr != NULL){ 
    currentPtr = currentPtr->nextPtr; 
} 
currentPtr->nextPtr = newPtr; 

这里做的事情是,它遍历列表,直到currentPtr等于空。 然后,您试图通过空指针(currentPtr->nextPtr)分配struct字段,这会导致分段错误。

0

好吧,这在这里:

while(fpeek(fptr) != EOF) { 
     i = 0; 
     while(fpeek(fptr) != ' '){ 
     word[i] = fgetc(fptr); 
     i++; 
     printf("%d",i); 
     } 
     word[i] = '\0'; 
     insert(&startPtr, word); 
     printf("%c", word[4]); 
     word[0] = '\0'; 
    } 

当我跑我的全部代码,它打印12345ooooooooooooooooooooooo ...等。在我的测试文件中,第一个单词是“Hello”,所以这就是无限'o的来源。如果外部循环是无限的,那么第二个while循环不会执行多次?我的意思是,为什么第二次印刷声明是唯一重演的声明?