【问题标题】:Reading a text file into a LinkedList将文本文件读入 LinkedList
【发布时间】:2013-10-14 21:24:08
【问题描述】:

我正在尝试读取文本文件并将其中的字符串逐字添加到链接列表中。我是 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;
    }

【问题讨论】:

    标签: c string linked-list


    【解决方案1】:

    首先,检查 fopen() 等库函数的返回值。

    其次,看simonc的回答。

    第三,在这个循环之后:

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

    currentPtr 为空,因此currentPtr-&gt;nextPtr = newPtr; 将取消引用空指针。 也许像

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

    更多的是您正在寻找的。​​p>

    最后,

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

    应该是

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

    主要是

    char fpeek(FILE *);
    

    应该是

    int fpeek(FILE *);
    

    【讨论】:

    • 我进行了更改,段错误消失了,但现在我想我在某个地方遇到了无限循环。另外,检查库函数的返回值是什么意思?
    • 您应该检查 fopen() 的返回值是否为空。在这种情况下,它看起来不像,但它是一种很好的编码风格来检查。至于循环,我不确定,您的嵌套 fpeek() 循环很难遵循。
    • 这个 'word[strlen(word)] = '\0';'应该是 'word[i] = '\0';
    • 使用 printf 我发现它在我的外部 fpeek() 循环中。这是否意味着循环永远找不到文件的结尾?我不确定。
    • 问题可能是 fseek() 返回 char 而不是 int。看到这个答案stackoverflow.com/questions/9378073/getcfp-causing-trouble/…
    【解决方案2】:

    我快速查看了您的代码,我很确定段错误问题就在这里:

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

    它的作用是遍历列表直到currentPtr 等于null。 然后您尝试通过空指针 (currentPtr-&gt;nextPtr) 分配结构字段,这会导致分段错误。

    【讨论】:

      【解决方案3】:

      好的,就在这里:

      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';
          }
      

      当我运行完整的代码时,它会打印 12345oooooooooooooooooooooooo... 等等。在我的测试文件中,第一个单词是“Hello”,所以这就是无限 'o' 的来源。如果外循环是无限的,那么第二个while循环不会执行多次吗?我的意思是,为什么第二个打印语句是唯一重复的?

      【讨论】:

        猜你喜欢
        • 2023-04-09
        • 1970-01-01
        • 2016-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-16
        相关资源
        最近更新 更多