[英]Struct variables are not being saved correctly when printing linked list?
我有一個鏈表,我正在嘗試插入一個新節點,這似乎是成功插入我希望它去的節點,但變量一直是NULL。 有人能指出我導致這種情況發生的地方嗎?
這是打印和插入方法。
void printList(node *head)
{
node *p;
p = head;
if(p->next == NULL)
printf("No stops currently in the tour.");
else
{
while(p->next != NULL)
{
printf("Tour Stop: %s - Description: %s\n", p->name, p->name);
p = p->next;
}
}
}
void insertInOrder(node *head, node *newNode)
{
printf("What is the stop you want the new stop to come after? Type 'end' to insert at the end of the tour.");
char key[100];
scanf("%s", &key);
getchar();
node *p;
p = head->next;
if(head->next == NULL)
head->next = newNode;
else if(key == "end")
{
while(p->next != NULL)
p = p->next;
p->next = newNode;
printf("\nAT 57, newNode->info = %s and newNode->name = %s", newNode->info, newNode->name);
}
else
{
while(strcmp(p->name, key) != 0)
{
if(p->next == NULL)
{
printf("Couldn't find the tour stop you requested, inserting at end of tour.");
break;
}
p = p->next;
}
p->next = newNode;
}
這是我用來傳遞給insert方法的createNewNode方法
node* createNewNode()
{
node *newNode;
newNode = malloc(sizeof(struct node));
printf("Enter the name of the new tour stop.\n");
char newName[100];
fgets(newName, sizeof(newName), stdin);
newNode->name = newName;
printf("Enter information about the tour stop. Max number of characters you can enter is 1000.\n");
char newDescription[1000];
newNode->info = newDescription;
fgets(newDescription, sizeof(newDescription), stdin);
return newNode;
}
您沒有將字符串復制到結構中。 您只是將指針復制到createNewNode()
的局部變量:
char newName[100];
fgets(newName, sizeof(newName), stdin);
newNode->name = newName;
這意味着當您稍后訪問存儲的指針時,未定義的行為,因為它不再有效。
您需要在結構中包含字符空間,並在其中復制(或只讀取)字符串,以便在節點存在時保持分配。
這段代碼有很多問題,我甚至不知道從哪里開始。
printf("What is the stop you want the new stop to come after? Type 'end' to insert at the end of the tour.");
char key[100];
scanf("%s", &key);
getchar();
如果你絕對需要使用scanf(建議不要)讀取字符串,你應該在'%s'格式說明符之前添加一個最大字符,比如scanf(“%99s”,&key)。 您應該讀取99個字符而不是100個字符,以便空終止不會溢出您的數組。
else if(key == "end")
{
//code
}
這里不是將key的內容與const char *“end”進行比較,而只是將數組鍵的地址與const char *“end”的地址進行比較,您應該使用strcmp代替。 (甚至更好的strncmp )
node* createNewNode()
{
node *newNode;
newNode = malloc(sizeof(struct node));
printf("Enter the name of the new tour stop.\n");
char newName[100];
fgets(newName, sizeof(newName), stdin);
newNode->name = newName;
printf("Enter information about the tour stop. Max number of characters you can enter is 1000.\n");
char newDescription[1000];
newNode->info = newDescription;
fgets(newDescription, sizeof(newDescription), stdin);
return newNode;
}
這里新節點的名稱和信息指針將指向在返回createNewNode調用后釋放的內存。 這是未定義的行為,您的程序可能會出現段錯或更糟。
您應該將讀取緩沖區復制到堆上分配的新緩沖區,並將指針設置為指向它們,或者首先在堆上分配緩沖區。
int newDescriptionLength = strlen(newDescription) + 1; //plus 1 for null termination
char* newDescriptionCopy = malloc(newDescriptionLength);
strncpy(newDescriptionCopy, newDescription, newDescriptionLength);
newNode->info = newDescriptionCopy;
strncpy將確保在復制源字符串newDescription的所有字符后,newDescriptionCopy字符串以空值終止。
在釋放節點時應考慮分配的緩沖區。
此外,您還應該使用fgets讀取一個字符,因為提供准確的字符數不會使字符串終止。
您應該在深入研究問題之前解決這些問題,因為您的程序充滿了未定義的行為,並且在調試期間做出假設是不安全的。
從我所看到的你的代碼(你沒有打印調用函數或鏈表的init,如果有的話),看起來你永遠不會檢查第一個元素(即頭)。 所以當列表完成時為空,那么head將指向NULL。 因此,使用您的打印功能作為示例,您應該:
void printList(node *head)
{
node *p;
p = head;
// Check if the list contains anything
if (p == NULL)
{
printf("List is empty");
}
else
{
printf("Tour Stop: %s - Description: %s\n", p->name, p->name); // print first/head element
// Continue while there are more elements
while(p->next != NULL)
{
printf("Tour Stop: %s - Description: %s\n", p->name, p->name);
p = p->next;
}
}
}
你的插入函數可能是一樣的,所以你永遠不要插入任何東西?
注意 :放松在他的回答中也有一個非常有效的觀點
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.