【问题标题】:Error inserting string at the beginning of a Linked List在链接列表的开头插入字符串时出错
【发布时间】:2016-10-08 17:09:46
【问题描述】:

我一直在尝试编写一个将字符串插入到链表开头的程序,但是其中出现了一个小问题。我的代码如下。

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

struct node{
    char* data;
    struct node* next;
};



void insIni(struct node** hp, char* x){
    struct node* tmp = (struct node *)malloc(sizeof(struct node)); 
    tmp->data = x;
    tmp->next = *hp;
    *hp = tmp;
}

void printList(struct node* h){
    struct node* tmp = h;
    printf("\nList contents: \n");
    while (tmp != NULL){
        printf("%s,  ", tmp->data );
        tmp = tmp->next;
    }
    printf("\n");
}

int main(int argc, char const *argv[]){

    struct node* head = NULL;  

     char word [256];
     scanf("%s", word);  
    insIni(&head, word);
    scanf("%s", word);  
    insIni(&head, word);
    scanf("%s", word);  
    insIni(&head, word);

    printList(head);

    return 0;
}

我在链表的开头插入一个新字符串后,前面的元素也被更改为与刚刚插入的字符串相同,我该如何更改我的代码,以便链接的前面的元素列表保持不变,只添加开头的元素?

例如,如果我写 A B C,链接列表最终会打印为 C、C、C,而不是 C、B、A,。

【问题讨论】:

  • 它可以工作,但是 main() 中的scanf("%s", word); 每次都会将输入读入相同的字符数组。您可以将 isnsIni() 中的 tmp-&gt;data = x; 替换为 tmp-&gt;data = strdup(x);
  • 好的,该更改似乎解决了我的问题,但是在编译时我收到以下警告:内置函数“strdup”的隐式声明不兼容。这很危险吗?如果是这样,我该如何删除它?
  • 您需要#include &lt;string.h&gt; 才能使用 strdup() (注意:strdup 有点非标准)
  • strdup 是 POSIX,这是一个非常好的标准

标签: c data-structures linked-list


【解决方案1】:

您传递给 insIni 的值始终相同,因此所有节点都指向相同。您需要做的是数据的副本。

例如

void insIni(struct node** hp, char* x){
    struct node* tmp = (struct node *)malloc(sizeof(struct node)); 
    tmp->data = strdup(x);
    tmp->next = *hp;
    *hp = tmp;
}

char *p = malloc(strlen(x)+1);
strcpy(p, x);
tmp->data = p;

【讨论】:

  • 使用 strdup 的解决方案似乎有效,谢谢!但是,在编译时,我收到警告:内置函数“strdup”的隐式声明不兼容。这很危险吗?如果是这样,我该如何删除它?
  • @GeorgeFrancis 您需要包含适当的标题。假定 C 编译器发现没有原型的任何函数都返回 int。 #include &lt;string.h&gt;
【解决方案2】:

scanf 将文本读入数组word。在调用insIni(&amp;head, word); 中,您不传递字符串,而是传递数组word 的地址。在insIni 行中的tmp-&gt;data = x; 中,您将该地址复制到元素数据中。但它仍然是来自函数main 的数组word。所以接下来scanf 将覆盖该数组的内容。对insIni(&amp;head, word); 的下一次调用会将相同的地址分配给下一个结构。因此,您实际需要的是在scanf 语句之前(或之后)或insIni 中为字符串分配内存。像char * word; 这样的东西而不是char word [256];word = malloc(256); 在每个scanf 前面都可以完成这项工作。此外,scanf 很危险,因为缓冲区溢出,所以您可能想阅读以下内容: How to prevent scanf causing a buffer overflow in C?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-29
    • 1970-01-01
    • 2020-01-06
    • 2021-12-28
    • 2021-01-18
    • 1970-01-01
    相关资源
    最近更新 更多