简体   繁体   中英

Printing a linked list in C program

I have see some other posts about how to print out a linked list, but none of them were helpful to me, so I decided to post my own code. Here is the problem:

I am able to add in a name and age perfectly fine, but the second I add in another name and age it overwrites the previous one.

So if i input:

Matt and 21, then charles and 34. It will only output charles and 34. How do I get it to output everything? Thank you in advance for the help! :)

Here is my code:

#include<stdlib.h>
#include<stdio.h>
#include<malloc.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
#define pause system ("pause")

// prototype variables
struct node * initnode(char*, int);
void printnode(struct node*);

struct node{
    char name[20];
    int age;
    struct node *next;
};

struct node *head = (struct node*) NULL;
struct node *end = (struct node*) NULL;

struct node* initnode(char *name, int age){
    struct node *ptr;
    ptr = (struct node*) calloc(3, sizeof(struct node));
    if(ptr == NULL) 
        return (struct node*) NULL;
    else {
        strcpy(ptr->name, name);
        ptr->age = age;
        return ptr;
    }
}

void printnode(struct node *ptr) {
    printf("Name -> %s\n", ptr->name);
    printf("Age -> %d\n", ptr->age);
}


main() {
    char name[20];
    int age, choice = 1;
    struct node *ptr;
    while(choice != 3){
        system("cls");
        printf("1. Add a name\n");
        printf("2. List nodes\n");
        printf("3. Exit");
        printf("\nEnter Menu Selection: ");
        scanf("%d", &choice);
        switch(choice) {
        case 1: printf("\nEnter a name: ");
            scanf("%s", name);
            printf("Enter age: ");
            scanf("%d", &age);
            ptr = initnode(name, age);
            break;
        case 2: if(ptr == NULL) {
                printf("Name %s not found\n", name);
            } else 
                printnode(ptr);
            pause;
            break;
        case 3: exit(3);
        default: printf("Invalid Entry");
        }// end of switch


    }// end of main

}

Oh and I know that some of the "#include's" might not be useful. I've been adding and deleting code all day.

Just a remamrk:

ptr = (struct node*) calloc(3, sizeof(struct node));

is wrong because you are allocating 3 * sizeof(struct node) and it should be

ptr = (struct node*) calloc(1, sizeof(struct node));

Your code is missing many things. you are not linking the node you create to any linked list. in the whole code you are not using next . You have to work more on this code.

The problem is not only coming from the print of the linked list. the problem come from how to create the linked list

I can suggest to you a template of linked list which can help in developing such program. this template contains functions and macro to treate linked list like

  • adding to linked list in the head
  • adding to linked list in the tail
  • removing from linked list...

you can get the linked list template (list.h) from this link

The following link contains an example of how use it

Please refer to this paragraph in the above link

With very little modifications (removing hardware prefetching of list items) we can also use this list in our applications. A usable version of this file is available here for download.

While you have defined head and end pointers, which would make a linked list, you are not actually using these to store your new information. After having created your new node and storing it in the ptr variable, you don't actually store it in the list.

I would suggest adding another method, addnode , which adds this newly-created node to the linked list defined by the head and end pointers.

void addnode(struct node *ptr) {
    if (end == NULL) {
        head = ptr;
        end = ptr;
    }
    else {
        end = end->next = ptr;
    }
}

Broadly, we check if we have any items already in the list; if not, both the start and the end of the list will be represented by the same node: the only one in the list! Otherwise, we let the node after the current end be the node to add, and then move our global end pointer to what is now the last node.

This allows us to maintain a chain of more than one node (entry in the list). We must then, when printing the entire list, follow this entire chain, from the first node ( head ) to the last. We can do this with a simple loop: instead of simply calling printnode() on the temporary ptr variable we maintain in main() , we write:

struct node *current = head;
while (current != end) {
    printnode(current);
    current = current->next;
}

This line here:

ptr = initnode(name, age);

is why you're always overwriting the name/age, because you declared a local node called ptr and every time you add a value you overwrite that node with the next node.

See that struct node *next; element in your node structure? You need to point that to the next node created in order to have more than 1 node, sort of like:

ptr->next = initnode(name, age);

There's a special case of the first node when it comes to linked lists, your first node ptr is empty, so when your list is 0 in length, you need to set ptr from init_node() , the next time you need to set ptr 's next element, and then you need to update ptr so that it is the current node:

ptr = ptr->next;

Of course doing this causes you to "loose" the start for the list. That's where your head comes in. When you start if you initialize head to ptr , then never move head, you'll always remember where the start of your list is.

You also have a variable:

struct node *end = (struct node*) NULL;

You'll have to keep updating that with every addition in order to always point to the last element added... if you care. Normally end or last or tail pointers are if you're going to make a double linked list.

I am able to add in a name and age perfectly fine, but the second I add in another name and age it overwrites the previous one.

Your code doesn't overwrite the previous node, it replaces it with a new node and leaks the one you had before. (A leak is a piece of memory that you've allocated and then lost any pointers to, so that you can never deallocate it.) Here's the line that creates a new node:

ptr = initnode(name, age);

If ptr is the pointer to the first node in the list, you should be adding the new node to the end of the list, not assigning it to ptr .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM