[英]code not printing linked list C
I am writing C code to implement linked list.But while printing the contents of the list it prints the values taken for last node only.I have been debugging for long.Please help. 我正在编写C代码来实现链接列表,但是在打印列表内容时仅打印最后一个节点的值,我已经调试了很长时间了,请帮忙。
#include <stdio.h>
#include <malloc.h>
struct list {
char *name;
char *type;
int occurance;
struct list *prev;
struct list *link;
};
struct list *start=NULL,*ptr,*newnode;
void main() {
int choice = 0;
char name1[10], type1[10];
int occ;
do {
printf("Enter name:");
scanf("%s", name1);
printf("Enter type:");
scanf("%s", type1);
printf("Enter occurance:");
scanf("%d", &occ);
newnode = (struct list *)malloc(sizeof(struct list));
newnode->link = NULL;
newnode->prev = NULL;
newnode->name = name1;
newnode->type = type1;
newnode->occurance = occ;
if(newnode == NULL) {
printf("Memory could not be allocated!");
// exit(0);
}
if(start == NULL) {
start = newnode;
ptr = start;
printf("start is: %s", start->name);
}
else if(start->link == NULL) {
start->link = newnode;
newnode->prev = start;
ptr = newnode;
}
else {
ptr->link = newnode;
newnode->prev = ptr;
ptr = ptr->link;
}
printf("Enter 1 to continue: ");
scanf("%d", &choice);
} while(choice == 1);
// display
ptr = start;
while(ptr != NULL) {
printf("%s ", ptr->name);
printf("%s ", ptr->type);
printf("%d \n", ptr->occurance);
ptr = ptr->link;
}
}
I have tried making start and newnode
local variables as well but it doesn't work. 我也尝试过使start和
newnode
局部变量,但是它不起作用。
Your cannot use equal operator to assign a char *
. 您不能使用equal运算符来分配
char *
。 Instead you must use function strcpy
. 相反,您必须使用功能
strcpy
。
Do not do this: 不要这样做:
newnode->name=name1;
newnode->type=type1;
But do this: 但是这样做:
strcpy(newnode->name, name1);
strcpy(newnode->type, type1);
Currently your whole char*
are pointing to the same memory block. 当前,您的整个
char*
都指向同一内存块。
Edit: Since you are using pointers, you must allocate memory before copying value from one pointer to another (or you will encounter segfaults). 编辑:由于使用的是指针,因此必须在将值从一个指针复制到另一个指针之前分配内存(否则您将遇到段错误)。 So you also need to allocate your node's name and type memories with
malloc
: 因此,您还需要使用
malloc
分配节点的名称并键入malloc
:
//allocate memory of node's name attribute with the same amount as name1 (+1 for null terminating character)
newnode->name = malloc(sizeof(char) * (strlen(name1)+1));
newnode->type= malloc(sizeof(char) * (strlen(type1)+1));
There are several things to improve in your code so let's take it one by one. 您的代码有几处需要改进的地方,所以让我们一一介绍。 First, the behaviour you are seeing is because the structure members
name
and type
of all nodes in your linked list point to the same memory location, ie, to name1
and type1
respectively. 首先,您看到的行为是因为链接列表中所有节点的结构成员
name
和type
都指向相同的内存位置,即分别指向name1
和type1
。
struct list {
char *name;
char *type;
// other members
};
Here, name
is a pointer to a character and so is type
. 这里,
name
是指向字符的指针, type
。 In the do while
loop in main
, you read name and type of each node into the arrays name1
and type1
respectively in each iteration. 在
main
的do while
循环中,您在每次迭代中分别将每个节点的名称和类型读入数组name1
和type1
中。 Therefore, the previous values of name1
and type1
are overwritten and hence lost. 因此,
name1
和type1
的先前值将被覆盖并因此丢失。 Now you are assigning name1
and type1
to respective members of each newly created node. 现在,您要为每个新创建的节点的相应成员分配
name1
和type1
。
// after allocating memory for a new node
newnode->name = name1; // name1 evaluates to a pointer to name1[0]
newnode->type = type1; // type1 evaluates to a pointer to type1[0]
Therefore name
member of all nodes are pointing to name1
which only retains the last string read, and similarly type
member of all nodes point to type1
which also has the last string read. 因此,所有节点的
name
成员都指向仅保留最近读取的字符串的name1
,并且类似地,所有节点的type
成员指向也具有最近读取的字符串的type1
。
Now that we have discussed the behaviour of your program, what's the solution? 既然我们已经讨论了您的程序的行为,那么解决方案是什么? You keep name and type of each node from getting overwritten by the next values entered.
您可以防止每个节点的名称和类型被输入的下一个值覆盖。 You do this by allocating memory for them every time you read them for a new node.
为此,可以在每次为新节点读取它们时为它们分配内存。
newnode->name = strdup(name1); // make a copy of name1 before it's overwritten
newnode->type = strdup(type1); // make a copy of type1 before it's overwritten
strdup
allocates enough memory to copy the string passed to it. strdup
分配足够的内存来复制传递给它的字符串。 It essentially does the same thing as malloc
and strcpy
. 它本质上与
malloc
和strcpy
做相同的事情。 Read more about it here . 在此处了解更多信息。
Now let's come to other things starting from the top of your program. 现在让我们从程序的顶部开始讨论其他事情。
malloc.h
is deprecated and not standard. malloc.h
已过时,不是标准的。 Use stdlib.h
instead. stdlib.h
。 More here . main
function: int main(void);
main
函数设置了两个签名: int main(void);
and the other is int main(int argc, char *argv[]);
int main(int argc, char *argv[]);
More here . scanf
, you should guard against buffer overrun. scanf
读取字符串时,应防止缓冲区溢出。 If the user enters name and type which are longer than 9 characters, it will lead to undefined behaviour and even crash. scanf("%s", name1)
with scanf("%9s", name1)
. scanf("%s", name1)
替换为scanf("%9s", name1)
。 The 9
in the format string means that scanf
will read at most 9 non-whitespace characters. 9
表示scanf
将最多读取9个非空白字符。 One character space is left for the terminating null byte which it adds automatically. malloc
for NULL
immediately after the call. malloc
的返回值是否为NULL
。 You program as such will simply crash if malloc
fails to allocate memory. malloc
未能分配内存,您的程序将很容易崩溃。 else if
block in your do while loop
. do while loop
,您do while loop
else if
块。 It will never be entered except in the first iteration of the loop when it makes start->previous = start
which is not what you want. start->previous = start
这不是您想要的),否则它将永远不会输入。 start->previous
should always be NULL
. start->previous
应该始终为NULL
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.