簡體   English   中英

代碼不打印鏈表C

[英]code not printing linked list C

我正在編寫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;
    }
}

我也嘗試過使start和newnode局部變量,但是它不起作用。

您不能使用equal運算符來分配char * 相反,您必須使用功能strcpy

不要這樣做:

newnode->name=name1;
newnode->type=type1;

但是這樣做:

strcpy(newnode->name, name1);
strcpy(newnode->type, type1);

當前,您的整個char*都指向同一內存塊。

編輯:由於使用的是指針,因此必須在將值從一個指針復制到另一個指針之前分配內存(否則您將遇到段錯誤)。 因此,您還需要使用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));

您的代碼有幾處需要改進的地方,所以讓我們一一介紹。 首先,您看到的行為是因為鏈接列表中所有節點的結構成員nametype都指向相同的內存位置,即分別指向name1type1

struct list {
    char *name;
    char *type;
    // other members
};

這里, name是指向字符的指針, type maindo while循環中,您在每次迭代中分別將每個節點的名稱和類型讀入數組name1type1中。 因此, name1type1的先前值將被覆蓋並因此丟失。 現在,您要為每個新創建的節點的相應成員分配name1type1

// 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]

因此,所有節點的name成員都指向僅保留最近讀取的字符串的name1 ,並且類似地,所有節點的type成員指向也具有最近讀取的字符串的type1

既然我們已經討論了您的程序的行為,那么解決方案是什么? 您可以防止每個節點的名稱和類型被輸入的下一個值覆蓋。 為此,可以在每次為新節點讀取它們時為它們分配內存。

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分配足夠的內存來復制傳遞給它的字符串。 它本質上與mallocstrcpy做相同的事情。 在此處了解更多信息。

現在讓我們從程序的頂部開始討論其他事情。

  • malloc.h已過時,不是標准的。 請改用stdlib.h 這里更多。
  • C標准為main函數設置了兩個簽名: int main(void); 另一個是int main(int argc, char *argv[]); 這里更多。
  • 使用scanf讀取字符串時,應防止緩沖區溢出。 如果用戶輸入的名稱和類型超過9個字符,將導致不確定的行為,甚至崩潰。 您應將scanf("%s", name1)替換為scanf("%9s", name1) 格式字符串中的9表示scanf將最多讀取9個非空白字符。 終止的空字節保留一個字符空間,它會自動添加。
  • 調用后立即檢查malloc的返回值是否為NULL 這樣,如果malloc未能分配內存,您的程序將很容易崩潰。
  • do while loop ,您do while loop else if塊。 除非在循環的第一個迭代start->previous = start這不是您想要的),否則它將永遠不會輸入。 start->previous應該始終為NULL

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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