链表在循环中调用时不接受新节点



代码的问题是,我不能在使用switch时分配新节点而不影响先前分配的节点。它继续使用最新给定的节点输入重新分配

链表结构节点 链表的结构如下所示

typedef struct stringData {
char *s;
struct stringData *next;
} Node;

创建插入和打印链表下面是创建和打印链表

的代码
Node *createNode(char *s) {
Node *newNode = (Node *)malloc(sizeof(Node));
newNode->s = s;
newNode->next = NULL;
return newNode;
}
void insert(Node **link, Node *newNode) {
newNode->next = *link;
*link = newNode;
}
void printList(Node *head) {
while (head != NULL) {
printf("%sn", head->s);
head = head->next;
}
}

主要当我编译时,我不能在运行时分配链表,也就是说,当我必须在交换机中分配多个节点时。我如何才能消除这个错误?

Node *head = NULL;
Node *tail = NULL;
Node *n;
char message_arr[10] = {};
int choice =0;  
int len;
char str[20];
n = createNode("Hi");
insert(&head, n);
tail = n;


n = createNode("Hello");
insert(&tail->next, n);
tail = n;




n = createNode("How are you");
insert(&tail->next, n);
tail = n;
int index,ind;       


while(choice!=6)       

{
printf("nChoose one option from the listn");  
printf("n 1. New Message  2. Display all messages  3.Delete all messagesn");  
printf("nEnter your choice?n");         
scanf("n%d",&choice);  
switch(choice)  
{  
case 1:  
printf("nEnter new messagen");
scanf("%s",message_arr);

n = createNode(message_arr);
insert(&tail->next, n);
tail = n;
break;  

case 2:  
printf("nMessages so far:nn");
printList(head);     
break;  

case 3:
printf("nDeleting all messages.....n");
free_list(head);
printf("nMessages deleted.....n");
break;
case 6:
exit(0); 

break;  
default:  
printf("Please enter valid choice."); 



}  


}
return(0);    

从列表1中选择一个选项。2.新信息阅读留言显示所有消息4。删除消息5.单击"下一步"。删除所有消息

Enter your choice?
1
Enter new message
morning

Choose one option from the list 1. New Message  2. Read a Message  3. 
Display all messages  4. Delete a message 5.Delete all messages
Enter your choice?
1
Enter new message
giya
Choose one option from the list
1. New Message  2. Read a Message  3. Display all messages  4. Delete a 
message 5.Delete all messages
Enter your choice?
3
Messages so far:
Hi
Hello
How are you
giya
giya

在调用开关的第一个case时输入"新消息";两次,则已经分配的第一条消息也被第二条消息替换,并显示两次为giyagiya

>当我在呼叫开关的第一个情况下输入"新消息"时;两次,则已经分配的第一条消息也被第二条消息取代,并显示两次giyagiya

原因是所有新创建的节点s成员指针都指向同一个缓冲区message_arr。这就是为什么在显示它们时,它们都打印message_arr缓冲区的当前内容,这是您输入的最后一个值。

为了更好地理解它:

首先在列表中为新创建的节点输入值morning:

---------
--->|   |   |-->NULL     
---------            
|
|                   message_arr
|                  ---------------------
|_________________>|m|o|r|n|i|n|g| | | |
---------------------

则您已在列表中为新创建的节点输入值giya:

---------   ---------
--->|   |   |-->|   |   |--->NULL  
---------   ---------         
|           |
|           |        message_arr
|           |----> ---------------------
|----------------->|g|i|y|a| | | | | | |
---------------------

为了解决这个问题,在创建新节点后,将内存分配给Node结构的s指针成员,并将message_arr缓冲区的内容复制到分配的内存中。或者,您可以使用strdup()来解决此问题:

Node *createNode(char *s) {
Node *newNode = (Node *)malloc(sizeof(Node));
newNode->s = strdup(s);    // <----------
strdup()函数返回一个指向新字符串的指针,该新字符串是传递给它的字符串的副本。strdup()为新字符串分配内存并返回它的指针。确保使用free()释放它,一旦你完成它。注意strdup()不是C标准的一部分。

因为,您已经将CC++标记添加到您的问题中,这是这种初始化方式的重要一点:

char message_arr[10] = {};

空初始化项符合C++标准,但在C中不符合,尽管一些C编译器接受它。

C中,您应该这样做:

char message_arr[10] = {0};

C++中也是可以接受的。

遵循良好的编程习惯,确保检查malloc(),scanf()等的返回值。另外,请确保检查choice的用户输入是否有效。您应该检查,当用户为choice提示符输入一些字符而不是数字时会发生什么!

最新更新