簡體   English   中英

打印鏈表時,結構變量未正確保存?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM