繁体   English   中英

从链表中删除一个节点

[英]Deleting a node from linked list

我正在尝试删除由出生编号给出的节点,例如9403133410 下次我打印链接列表时,我只想在 output 中看到 Mike。

这是我要加载到链表中的 file.txt

***
Dave
9403133410
***
Mike
9458133410
***
Dave
9403133410

这是我的名为node_t的结构:

typedef struct node {
    char                *presenter;
    char                *birth_number;
    struct node         *next;
}node_t;
node_t *node_new(){
    node_t *node = malloc(sizeof(node_t));

    node->next = NULL;
    node->presenter = NULL;
    node->birth_number = NULL;

    return node;
}

这是我的负载 function

node_t *node_load(const char *file){
    int counter = 0, number_entries = 0, db_loaded = 0;
    char buffer[BUFFER_SIZE];
    dbFile = fopen(DATABASE_FILE, "r");

    if (!dbFile){printf("Zaznamy neboli najdene!\n");}

    node_t *ptr = NULL, *head = NULL;

    while(fgets(buffer, BUFFER_SIZE, dbFile) != NULL){
        switch(counter++){
        case 0:
            if (!ptr){
                ptr = node_new();
                head = ptr;
            }
            else{
                ptr->next = node_new();
                ptr = ptr->next;
            }
            number_entries++;
            break;
        case 1:
            ptr->presenter = strdup(buffer);
            break;
        case 2:
            ptr->birth_number = strdup(buffer);
            counter = 0;

            break;
        }
   }
    fclose(dbFile);
    return head;
}

这是我的删除节点 function:

void node_delete(node_t *head){
    node_t *temp, *previous;
    temp = head;
    char birth_n[14];

    scanf("%s", &birth_n);
    strcat(birth_n, "\n");

    for ( ; temp->next != NULL; temp = temp->next){
        if (strcmp(birth_n, temp->birth_number) == 0){
            if (temp == head){
                head = temp->next;
            }
            else{
                previous = temp;
                previous->next = temp->next;
            }
            free(temp);
        }
    }
}

所以我正在尝试删除其出生编号给出的节点。

function 没有意义。

首先将搜索到的字符串通过参数传递给function。

其次,function 处理指向头节点的指针值的副本。 更改 function 中的副本不会影响用作 function 参数的原始指针。

至少不是这个电话

scanf("%s", &birth_n);

你应该写

scanf("%13s", birth_n);

也不清楚你为什么要 append 换行符 '\n'

strcat(birth_n, "\n");

这个for循环

for ( ; temp->next != NULL; temp = temp->next){

当传递的指针是 null 指针时,可以调用未定义的行为。 此外,当列表仅包含一个节点时,即使该节点包含目标字符串,也会跳过循环。

此外,当删除具有目标字符串的节点时,循环不会终止。

并在循环的第三个表达式中使用指针 temp

temp = temp->next

在此声明之后

free(temp);

调用未定义的行为。

function可以看如下方式

int node_delete( node_t **head, const char *birth_number )
{
    while ( *head != NULL && strcmp( ( *head )->birth_number, birth_number ) != 0 )
    {
        head = &( *head )->next;
    }

    int success = *head != NULL;

    if ( success )
    {
        node_t *temp = *head;
        *head = ( *head )->next;
        free( temp );
    }

    return success;
}

在 main 中,您必须输入将要搜索的目标字符串,并且 function 至少被称为

node_delete( &head, birth_number );

您还可以检查 function 的返回值,以确定是否删除了具有指定字符串的节点。

如果您启用编译器警告并将警告视为错误,您可能会看到如下错误消息:

format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[14]’ [-Werror=format=]
      |     scanf("%s", &birth_n);
      |            ~^   ~~~~~~~~
      |             |   |
      |             |   char (*)[14]
      |             char *

这告诉您scanf%s格式字符串与您提供的内容不兼容。 您正在为它提供一个指向字符指针的指针,而不仅仅是您明确想要的字符指针。

您应该只将birth_n传递给scanf function,如下所示:

 scanf("%s", birth_n);

这与链表无关,而是 C 中的基本输入和字符串处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM