我一直试图写一个程序,插入一个字符串到链表的开始,但是有一个小问题在它。我的代码如下:
#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,.
传递给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;
scanf
将文本读入数组word
。在insIni(&head, word);
调用中,您不传递字符串,而是传递数组word
的地址。在insIni
的tmp->data = x;
行中,将该地址复制到元素数据中。但它仍然是函数main
中的数组word
。所以接下来scanf
将覆盖该数组的内容。下一次对insIni(&head, word);
的调用将给下一个结构体分配相同的地址。因此,您实际需要的是为字符串分配内存,要么在scanf
语句之前(或之后),要么在insIni
中。像char * word;
这样的东西代替char word [256];
和word = malloc(256);
在每个scanf
前面将完成这项工作。此外,scanf
是危险的,因为缓冲区溢出,所以你可能想读这个:如何防止扫描导致缓冲区溢出在C?