我只允许使用以下标题
#include <stdio.h>
#include <stdlib.h>
我将struct student
定义如下:
struct dict
{
char* word;
struct dict* link;
};
有很多功能,但现在只有一个我有问题的功能。 此函数在链接的末尾插入具有特定名称的结构字典。
struct student *Linsert(struct dict *list, char *name)
{
struct student *pnew;
struct student *pn;
int exist = 1;
pnew = (struct dict *)malloc(sizeof(struct dict));
pnew -> next = NULL;
pnew -> name = name;
if (list != NULL)
{
for (pn = list; pn -> next != NULL; pn = pn -> next) ;
pn -> next = pnew;
}
else
list = pnew;
return list;
}
使用以下功能
//print all the values in the list void printList(struct dict* list);
我这样做了:
int main(void)
{
struct dict *list = NULL;
char *name;
while (1) {
scanf("%s", name);
if (name == 'Q')
break;
list = Linsert(list, name);
printList(list);
}
return 0;
}
让我们说输入,我输了三个
apple
banana
和orange
,我的结果显示了我上次输入的三个内容。
这里有什么问题?
答案 0 :(得分:3)
我发现您的代码有两个问题:
scanf
一个大小足以存储输入字符串的char
数组,而不仅仅是一个字符指针。Linsert
的字符串(使用strdup
)。答案 1 :(得分:2)
单独的main
代码段存在一大堆问题:
name
是一个未初始化的指针;它指向内存中未分配且允许使用的某个未知位置,因此导致未定义的行为。也许您希望char name[20]
在堆栈上分配20 char
的数组,并让scanf
将输入存储在此缓冲区中。
您正在将char*
(指向字符串开头的指针)与单个char
'Q'
进行比较 - 您正在比较指针和整数值正如您的编译器警告会告诉您的那样。您没有比较值'Q'
的字符串内容,而是比较name
的内存地址和'Q'
的整数值。如果要将字符串name
与字符串"Q"
进行比较,请使用strcmp
并检查返回值是否为0。
你也希望复制传递给Linsert
的变量,否则,你已经注意到,你每次都会将指针传递给内存中的同一个位置,并对此进行更改内存块将改变你的每个项目。
如果你打开编译器警告,你会收到更多警告。
答案 2 :(得分:1)
您没有为名称分配任何内存,因此scanf正在写入某个随机位置,并在每次循环时覆盖它。
答案 3 :(得分:1)
一个问题是您没有为word
成员分配存储空间来指向。您还没有为name
指定空间。这是麻烦的主要原因。
您需要为name
分配空间;最简单的方法是:
char name[128];
您需要分配空间来存储单词,并且需要将name
的内容复制到word
中,这样当下一行覆盖name
时,它不会破坏已保存的word
。
调整代码,您可以使用:
struct student *Linsert(struct dict *list, char *name)
{
struct student *pnew;
struct student *pn;
pnew = (struct dict *)malloc(sizeof(struct dict));
if (pnew == 0)
...error...
pnew->next = NULL;
pnew->word = malloc(strlen(name) + 1);
if (pnew->word == 0)
...error...
strcpy(pnew->word, name);
if (list != NULL)
{
for (pn = list; pn->next != NULL; pn = pn->next)
;
pn->next = pnew;
}
else
list = pnew;
return list;
}
不要忽略内存分配的错误检查 - 尽管很痛苦。当你忘记时它会咬你。
从风格上讲,不要在->
或.
周围使用空格;它们是非常紧密绑定的运算符,它们不应像其他二元运算符那样间隔开。
有一个方便的函数,strdup()
,重复一个字符串,但它不是标准的C(它是标准的POSIX)。
答案 4 :(得分:0)
由于name
是一个char指针,因此对每个dict
结构字段的赋值将使用它指向的最新值。