链接的字符串列表对于每个节点具有相同的字符串
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链接的字符串列表对于每个节点具有相同的字符串相关的知识,希望对你有一定的参考价值。
我正在尝试创建一个链表,每个节点都存储一个字符串,但我遇到的问题是每个节点最终在每个节点中存储相同的字符串。在main()的末尾,我打印出存储在每个节点中的单词,它总是只重复为整个列表输入的最后一个字符串。
我不知道发生了什么,因为如果我把它变成一串字符就可以很好地工作,每个字符都存储在正确的节点中。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct wordnode {
char *word;
struct wordnode *next;
};
struct wordnode *link = NULL;
void addword(char *aword);
int main(void) {
char *aword;
int i;
for(i = 0; i < 10; i++) {
scanf(" %s", aword);
addword(aword);
}
printf("\n");
for(; link != NULL; link = link->next) {
printf("|%s ", link->word);
}
printf("|\n");
return 0;
}
void addword(char *aword) {
struct wordnode *cur, *prev, *new_node;
new_node = malloc(sizeof(struct wordnode));
new_node->word = aword;
for(cur = link, prev = NULL; cur != NULL; prev = cur, cur = cur->next) {
;
}
new_node->next = cur;
if(prev == NULL) {
link = new_node;
} else {
prev->next = new_node;
}
}
答案
代码中存在许多问题。其中一些已被提及。代码将是这样的。代码末尾的解释。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define STR2(x) #x
#define STR(X) STR2(X)
#define MAXWORD 10
#define MAXWORDLEN 20
struct wordnode {
char *word;
struct wordnode *next;
};
struct wordnode* addword(char *aword, struct wordnode *link);
void printList(struct wordnode*link);
void freeList(struct wordnode *link);
int main(void) {
char aword[MAXWORDLEN+1];
struct wordnode *link = NULL;
for(size_t i = 0; i < MAXWORD; i++) {
if( scanf("%" STR(MAXWORDLEN) "s", aword[i]) == 1 ){
link = addword(aword, link);
}
else{
fprintf(stderr, "%s\n","Error in input" );
exit(1);
}
}
printList(link);
freeList(link);
return 0;
}
void printList(struct wordnode*link){
while(link){
printf("%s \n", link->word);
link = link->next;
}
}
void freeList(struct wordnode *link){
struct wordnode *temp;
while(link){
temp = link;
link = link->next;
free(temp);
}
}
struct wordnode* addword(char *aword, struct wordnode *link) {
struct wordnode *new_node = malloc(sizeof(struct wordnode));
if( new_node == NULL){
fprintf(stderr, "%s\n", "Error in malloc");
exit(1);
}
new_node->word = strdup( aword );
if( new_node->word == NULL){
fprintf(stderr, "%s\n", "Error in strdup" );
exit(1);
}
new_node->next = NULL;
if( link == NULL){
return new_node;
}
struct wordnode *cur = link;
while( cur->next != NULL ){
cur = cur -> next;
}
cur->next = new_node;
return link;
}
您想存储一些字符串(空终止的char数组),然后您想在列表中添加它们。同样从您的示例实现中,您尝试将其添加到尾部的列表中。
总结一下 -
scanf
需要一个指向某个存储器的指针,它可以存储输入的数据。但你的未初始化。- 其次,你复制字符串的方式,它只是一个浅的副本(你让它指向一些已经存在的内存)。你需要使用
strdup
或malloc - memcpy
或malloc-strcpy
复制它。 - 如果POSIX
strdup()
不可用,您可以使用Jonathan Leffler提到的内容。 - 在这里你可以看到我们已经使用
freeList()
函数释放了已分配的内存。当您完成使用已分配的内存时 - 释放内存。 - 不要强制转换
malloc
的返回值。 - 还要检查
malloc
是否成功检查它的返回值。 - 您已将列表头用作全局变量。这里不需要它。
另一答案
char * aword
未初始化和定位。它应该是:
char aword[100];
(100只是一个数字,大小的数组。你可以用你想要的任何数字替换它)
另一答案
您尚未为字符串分配内存。因此,aword
将包含垃圾值并将其传递给scanf
是一种未定义的行为。让我们说aword
有0x7fffe4e0cdf0
和你的scanf
将字符串存储在地址0x7fffe4e0cdf0
并将此地址传递给addword
函数,你的结构成员word
也更新了相同的值。下一个scanf还将新值存储在aword
指向的相同内存中并传递给该函数。因此,所有链表中的word
指向相同的内存位置。理想的解决方案是为每个被扫描的字符串分配内存,并将其传递给“addword”函数。
以上是关于链接的字符串列表对于每个节点具有相同的字符串的主要内容,如果未能解决你的问题,请参考以下文章
Python:如何将具有相同变量类型的多个列表合并到一个列表列表中?