当前位置: 首页 > 知识库问答 >
问题:

C-双链表总是空的

万知
2023-03-14

我正在用以下数据结构编写双向链表程序:

typedef struct telephoneBookNode {
    int id;
    char name[NAME_LENGTH];
    char telephone[TELEPHONE_LENGTH];
    struct telephoneBookNode * previousNode;
    struct telephoneBookNode * nextNode;
} TelephoneBookNode;

typedef struct telephoneBookList {
    TelephoneBookNode * head;
    TelephoneBookNode * tail;
    TelephoneBookNode * current;
} TelephoneBookList;

在下面的函数中,我将文本文件中的数据读取到链表中,文件内容如下所示:

/*100, Alice, 0411112222
101, Bob, 0411112222
102, Ali, 0411112223*/

TelephoneBookList * commandLoad(char* fileName) {
    TelephoneBookList *(*createList)(TelephoneBookNode*, char[]) = createTelephoneBookList;

    char entry[100], *temp1, *temp2;
    TelephoneBookList* aList = NULL;
    TelephoneBookNode* aNode = NULL;
    FILE* telephoneListFile = NULL;
    int countEntry = 0;
    Boolean check;

    telephoneListFile = fopen(fileName, "r");

    if (!telephoneListFile)
        return NULL;
    else {
        while (fgets(entry, 100, telephoneListFile)) {
            temp2 = strcpy(temp2, entry);
            temp1 = strtok(entry, "\n");
            check = addressBookEntryCheck(temp1);

            if (!check)
                return NULL;
            else
                //here I pass aNode pointer to the below function
                aList = (*createList)(aNode, temp2);
        }
        fclose(telephoneListFile);
        printf("printed"); //This line is reached when program complied
        return aList;
    }
}

这是创建列表的功能,问题可能在这里:它没有向列表中添加新节点,只是用新节点替换了第一个节点。最后,链接列表只有1条记录,这是文本文件中的最后一条。我该如何修复代码?谢谢!

TelephoneBookList * createTelephoneBookList(TelephoneBookNode* node, char entry[]) {
    TelephoneBookList* aList = malloc(sizeof *aList);
    TelephoneBookNode* aNode = (TelephoneBookNode*) malloc(sizeof *aNode);
    char *tokens;

    tokens = strtok(entry, ", ");
    aNode->id = atoi(tokens);

    tokens = strtok(NULL, ", ");
    strcpy(aNode->name, tokens);

    tokens = strtok(NULL, ", ");
    strcpy(aNode->telephone, tokens); //Just assigning values to a node

    //program always go to this block, means `node` is always null
    if (node == NULL) {
        aNode->nextNode = NULL;
        aNode->previousNode = NULL;
        node = aNode;

        aList->current = node;
        aList->head = node;
        aList->tail = node;
    }
    else { //This block is not reached
        while (node->nextNode)
            node = node->nextNode;

        node->nextNode = aNode;
        aNode->previousNode = node;

        aList->tail = node->nextNode;
    }
    return aList;
}

这是检查输入的功能:

Boolean addressBookEntryCheck(char entry[]) {
    char *tokens;

    tokens = strtok(entry, ", ");

    if(!tokens || strlen(tokens) < 1 || strlen(tokens) > 3)
        return FALSE;
    else {
        if (!isNumber(tokens))
            return FALSE;
        else {
            tokens = strtok(NULL, ", ");

            if (!tokens)
                return FALSE;
            else
            {
                tokens = strtok(NULL, ", ");

                if (!tokens)
                    return FALSE;
                else if (!isNumber(tokens) || strlen(tokens) != 10)
                    return FALSE;
                else
                    return TRUE;
            }
        }
    }
}

共有2个答案

凌景辉
2023-03-14
//program always go to this block, means `node` is always null
    if (node == NULL) {
    ....

这是因为函数的调用者传递了aNode,并且它在循环中从不更改。所以它总是传递相同的aNode值,即NULL

我还没有详细研究代码的逻辑,但我认为您可能希望通过aList-

淳于飞鸾
2023-03-14

每次你打电话

createTelephoneBookList

你创建一个新列表

TelephoneBookList* aList = malloc(sizeof *aList);

还可以复制到未初始化的指针

temp2 = strcpy(temp2, entry);

我建议你创建一个函数来创建列表标题,一个函数来添加新项目,例如。

aList = createList()
while (fgets(entry,sizeof(entry),fp)!=NULL)
{
  if (!addEntry(aList,entry))
  {
    fprintf(stderr, "failed additem item %s\n", entry);
  }
}
...

在addEntry中解析字符串

int id = 0;
char name[NAME_LENGTH];
char telephone[TELEPHONE_LENGTH];

p = strtok(entry, ","); // id
if (p != NULL) 
{  
  id = atoi(p);
  p = strtok(NULL, ","); // name, store to temporary string
  if (p != NULL )
  {
    strcpy(name,p);
    p = strtok(NULL, ","); // telephone number, store to temporary string
    if ( p != NULL )
    {
      strcpy(telephone,p);

      // here you can allocate the new node
    }
  }
}

// disclaimer omitted checks for length etc which any good program should have. also make sure you have room for \0

如果上述strtok中的任何一个失败,则返回0,否则分配一个新条目

TelephoneBookNode* aNode = malloc(sizeof(TelephoneBookNode));
aNode->id = id;
strcpy(aNode->name, name); 
strcpy(aNode->telephone, telephone); 

然后添加到您的aList

 类似资料:
  • 我试图交换链表中节点的位置,然后使用排序函数进行排序。这两个函数中的任何一个都有逻辑错误。当我运行这个程序时,它会无限循环。 更新代码

  • 我的程序不断崩溃。我觉得我的逻辑有问题。请帮忙!谢谢

  • 我是C语言的新手。我正在尝试创建一个双链接列表,其中数据字段是一个结构。但是当我输出元素时,只有结构的第一个字段正确显示。 所以,我有几个问题。我是否正确声明了节点值字段?我是否正确地插入了列表末尾的节点?双向链表项的输出正确吗?我的错误在哪里,如何纠正?

  • 我写了一个程序,通过双链表管理银行账户,但我发现取消程序有问题。 我仍然有同样的问题,即使我尝试了这个方法:-(pnt)-

  • 分段故障发生在“电流->prev->next=temp”上。我试图打印地址以了解为什么会发生这种情况,并发现在输入中第一个节点的前一个元素总是指向NULL。有人能解释为什么会发生这种情况以及如何修复它吗?谢谢你。

  • 这是我的remove函数,用于删除具有元素的节点。我得到了一个seg错误,我很确定这是因为temp->prev是前面的哨兵,所以从技术上来说,它不在双链表中。如果这是正确的,我实际上如何防止这种情况?如有任何帮助,不胜感激。 编辑:刚刚更新了代码,但仍然出现了Seg错误