Thread: Help in linked lists (probably a very stupid error)

  1. #1
    Registered User
    Join Date
    Dec 2014
    Posts
    7

    Help in linked lists (probably a very stupid error)

    Good afternoon, I'm kinda new with C, it's one of my subjects in the course I'm enrolled right now, but I've hit a brick wall when it comes to linked lists. We need to code a vending machine, where each product has a code, a name, an amount, a normal price and a discounted price for students. My problem is mainly when adding products. Now, this is probably a very stupid mistake but I can't figure it out... the problem in the code below is that it tells me dimension, name, amount, normalprice and studentprice are not declared in the read_list function. I'm using a code from an article from another website as a basis, and when I compare both code, I can't seem to find out why my code has compiling errors, while the other doesn't. I'm also not sure if doing it like this is gonna add the values to the list, which could also be a problem.


    Code:
    #include<stdio.h>#include<stdlib.h>
    #include<stdbool.h>
    
    
    struct test_struct
    {
            int code;
            int dimension;
            char name[20];
            int amount;
            float normalprice;
            float studentprice;
            struct test_struct *next;
    };
    
    
    struct test_struct *head = NULL;
    struct test_struct *curr = NULL;
    
    
    struct test_struct* read_list(void)
    {
    int i;
        printf("Insert the number of characters in the product's name.\n");
        scanf("%d",&dimension);
        printf("Insert the product's name.\n");
        for (i=0;i<dimension;++i)
         {scanf(" %c",&name[i]);}
        printf("Insert the amount of the product in stock.\n");
        scanf("%d",&amount);
        printf("Insert the normal price of the product.\n");
        scanf("%d",&amount);
        printf("Insert the normal price of the product.\n");
        scanf("%f",&normalprice);
        printf("Insert the students' discount price of the product.\n");
        scanf("%f",&studentprice);
    }
    
    
    struct test_struct* create_list(int code)
    {
        int i;
        printf("\n creating list with headnode as [%d]\n",code);
        read_list();
        struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
        if(NULL == ptr)
         {printf("\n Node creation failed \n");
         return NULL;}
        ptr->next = NULL;
        head = curr = ptr;
        return ptr;
    }
    
    
    struct test_struct* add_to_list(int code,bool add_to_end)
    {
    int i;
        if(NULL == head)
        {return (create_list(code));}
        if(add_to_end)
            printf("\n Adding product to end of list with value [%d]\n",code);
        else
            printf("\n Adding node to beginning of list with value [%d]\n",code);
    
    
        struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
        if(NULL == ptr)
        {
            printf("\n Node creation failed \n");
            return NULL;
        }
        ptr->code = code;
        ptr->next = NULL;
        if(add_to_end)
        {curr->next = ptr;
        curr = ptr;}
        else
        {ptr->next = head;
        head = ptr;}
        return ptr;
    }
    
    
    void print_list(void)
    {
        int i;
        struct test_struct *ptr = head;
        printf("\n -------Printing list Start------- \n");
        while(ptr != NULL)
        {printf("| Product code - %d | Product - ",ptr->code);
        for (i=0;i< ptr->dimension;++i)
         {printf("%c",ptr->name[i]);}
        printf(" | Normal price - %.2f | Student price - %.2f | Instances of the product - %d |\n",ptr->normalprice,ptr->studentprice,ptr->amount);
        ptr = ptr->next;}
        printf("\n -------Printing list End------- \n");
        return;
    }
    
    
    int main(void)
    {
    int i=0,ret=0;
        struct test_struct *ptr = NULL;
        print_list();
        for(i=1;i<3;i++)
            add_to_list(i,true);
        print_list();
        return 0;
    }

    Thanks in advance.


    EDIT: Changed the language of the printfs in print_list, forgot to change it.
    Last edited by Phantaminum; 12-30-2014 at 10:59 AM.

  2. #2
    Registered User
    Join Date
    Dec 2014
    Posts
    7
    Okay, I've managed it to compile, but it doesn't print the list correctly... it prints like below:

    -------Printing list Start-------|
    | Product code - 0 | Product name - | Normal price - 0.00 e | Student price - 0.00 e | Instances of the product available - 0 |
    | Product code - 1 | Product name - | Normal price - 0.00 e | Student price - 0.00 e | Instances of the product available - 0 |
    -------Printing list End-------

    Here's the new code:

    Code:
    #include<stdio.h>#include<stdlib.h>
    #include<stdbool.h>
    
    
    struct test_struct
    {
            int code;
            int dimension;
            char name[20];
            int amount;
            float normalprice;
            float studentprice;
            struct test_struct *next;
    };
    
    
    struct test_struct *head = NULL;
    struct test_struct *curr = NULL;
    
    
    struct test_struct* read_list(int code)
    {
      int i;
            struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
            printf("\n --- PRODUCT CODE %d --- \n",code);
            printf("Insert the number of characters in the product's name.\n");
            scanf("%d",&ptr->dimension);
            printf("Insert the product's name.\n");
            for (i=0;i<ptr->dimension;++i)
             {scanf(" %c",&ptr->name[i]);}
            printf("Insert the amount of the product in stock.\n");
            scanf("%d",&ptr->amount);
            printf("Insert the normal price of the product.\n");
            scanf("%f",&ptr->normalprice);
            printf("Insert the students' discount price of the product.\n");
            scanf("%f",&ptr->studentprice);
    }
    
    
    struct test_struct* create_list(int code)
    {
        struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
        int i;
        printf("\n creating list with headnode as [%d]\n",code);
            read_list(code);
        if(NULL == ptr)
         {printf("\n Node creation failed \n");
         return NULL;}
        ptr->next = NULL;
        head = curr = ptr;
        return ptr;
    }
    
    
    struct test_struct* add_to_list(int code,bool add_to_end)
    {
    int i;
        if(NULL == head)
        {return (create_list(code));}
        if(add_to_end)
            {printf("\n Adding product to end of list with value [%d]\n",code);
            read_list(code);}
            {printf("\n Adding node to beginning of list with value [%d]\n",code);
            read_list(code);}
    
    
        struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
        if(NULL == ptr)
        {
            printf("\n Node creation failed \n");
            return NULL;
        }
        ptr->code = code;
        ptr->next = NULL;
        if(add_to_end)
        {curr->next = ptr;
        curr = ptr;}
        else
        {ptr->next = head;
        head = ptr;}
        return ptr;
    }
    
    
    void print_list(void)
    {
        int i;
        struct test_struct *ptr = head;
        printf("\n -------Printing list Start------- \n");
        while(ptr != NULL)
        {printf("| Product code - %d | Product name - ",ptr->code);
        for (i=0;i< ptr->dimension;++i)
         {printf("%c",ptr->name[i]);}
        printf(" | Normal price - %.2f e | Student price - %.2f e | Instances of the product available - %d |\n",ptr->normalprice,ptr->studentprice,ptr->amount);
        ptr = ptr->next;}
        printf("\n -------Printing list End------- \n");
        return;
    }
    
    
    int main(void)
    {
    int i=0,ret=0;
        struct test_struct *ptr = NULL;
        print_list();
        for(i=0;i<2;i++)
            add_to_list(i,true);
        print_list();
            return 0;
    }
    Last edited by Phantaminum; 12-30-2014 at 12:59 PM.

  3. #3
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Consider things from our perspective. I don't know how your stuff is supposed to print. Showing how it prints now isn't helpful in helping you.

    How is your data supposed to look when it is printed? What are the differences between what you want and what you have?

  4. #4
    Registered User
    Join Date
    Dec 2014
    Posts
    7
    Sorry, effects of panicking. It's supposed to print what I input in the read_list function. Let me give you a practical example:

    -------Printing list Start-------

    -------Printing list End-------


    creating list with headnode as [0]


    --- PRODUCT CODE 0 ---
    Insert the number of characters in the product's name.
    5
    Insert the product's name.
    Pepsi
    Insert the amount of the product in stock.
    10
    Insert the normal price of the product.
    1.00
    Insert the students' discount price of the product.
    0.80


    Adding product to end of list with value [1]


    --- PRODUCT CODE 1 ---
    Insert the number of characters in the product's name.
    4
    Insert the product's name.
    7-up
    Insert the amount of the product in stock.
    10
    Insert the normal price of the product.
    0.95
    Insert the students' discount price of the product.
    0.75

    When I input this data when I execute the program, it prints this:

    -------Printing list Start-------

    | Product code - 0 | Product name - | Normal price - 0.00 e | Student price - 0.00 e | Instances of the product available - 0 |
    | Product code - 1 | Product name - | Normal price - 0.00 e | Student price - 0.00 e | Instances of the product available - 0 |

    -------Printing list End-------

    When it should print this:

    -------Printing list Start-------

    | Product code - 0 | Product name - Pepsi | Normal price - 1.00 e | Student price - 0.80 e | Instances of the product available - 10 |
    | Product code - 1 | Product name - 7-up | Normal price - 1.00 e | Student price - 0.80 e | Instances of the product available - 10 |

    -------Printing list End-------

    I think that's what you said was lacking, correct?

  5. #5
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Interesting. Okay, so obviously you have a problem storing the data in your list if everything is printing out 0. To confirm this, you can initialize all your structures with some weird number but that's probably not necessary.

    Let's help you map all this better.

    You can gather user input okay (I'm assuming). This is good.

    Then, allocate your product structure using malloc(). Keep the pointer returned by malloc() as this will be stored in your list.
    Code:
    struct product_info
    {
    /* put variables here */
    };
    
    struct list_node
    {
        struct list_node *next; // this is the next element in the list
        struct list_node *prev; // this is the previous element in the list
    
        struct product_info *prod_info; // this is a pointer to your product info
    };
    
    void some_function(/* ... */)
    {
     // create product_info structure using malloc()
    
     // add node to list, making sure the pointer is stored properly
    }
    
    int main(/* ... */)
    {
       // malloc single list_node structure as head of the list
    
      // add products to the list
       some_function(/* ... */);
    
        return 0;
    }
    
    // Access data from list like this :
    struct list_node *list = node_in_list_somewhere;
    list->prod_info->variable_name
    Now, I'm not sure if this is the best layout but there a couple of things worth noting. Make sure you're malloc'ing your product info structure and that your linked list's nodes contain a pointer and not the actual structure. A pointer is 4 or 8 bytes while a structure can become quite large.
    Last edited by MutantJohn; 12-30-2014 at 01:41 PM.

  6. #6
    Registered User
    Join Date
    Sep 2014
    Posts
    364
    Your function read_list should rerurn a pointer to an struct test_struct, but it returns nothing.

    And please, don't cast the returned value of malloc. This veils errors.
    Second, please make sure that the call of malloc is successfully.
    Code:
    struct test_struct *ptr;
    if ((ptr = malloc(sizeof(*ptr))) == NULL) return NULL;
    Other have classes, we are class

  7. #7
    Registered User
    Join Date
    Dec 2014
    Posts
    7
    So wait, you're saying I should make two structures? One to save the product info, which would be first in your code, and another to keep track of the structures I already have?

  8. #8
    Registered User
    Join Date
    Dec 2014
    Posts
    7
    Quote Originally Posted by WoodSTokk View Post
    Your function read_list should rerurn a pointer to an struct test_struct, but it returns nothing.

    And please, don't cast the returned value of malloc. This veils errors.
    Second, please make sure that the call of malloc is successfully.
    Code:
    struct test_struct *ptr;
    if ((ptr = malloc(sizeof(*ptr))) == NULL) return NULL;

    So, my read_list should be like this? It prints the same.

    Code:
    struct test_struct* read_list(int code)
    {
      int i;
            struct test_struct *ptr;
            if ((ptr = malloc(sizeof(*ptr))) == NULL)
             {return NULL;}
            printf("\n --- PRODUCT CODE %d --- \n",code);
            printf("Insert the number of characters in the product's name.\n");
            scanf("%d",&ptr->dimension);
            printf("Insert the product's name.\n");
            for (i=0;i<ptr->dimension;++i)
             {scanf(" %c",&ptr->name[i]);}
            printf("Insert the amount of the product in stock.\n");
            scanf("%d",&ptr->amount);
            printf("Insert the normal price of the product.\n");
            scanf("%f",&ptr->normalprice);
            printf("Insert the students' discount price of the product.\n");
            scanf("%f",&ptr->studentprice);
            return ptr;
    }

  9. #9
    Ultraviolence Connoisseur
    Join Date
    Mar 2004
    Posts
    555
    Yes that is correct as far as your read_list function.

    Your create_list function should be using the return value of read_list that you just created, but it doesnt:
    Code:
    struct test_struct* create_list(int code)
    {
        struct test_struct *ptr;
        int i;
        printf("\n creating list with headnode as [%d]\n",code);
        ptr = read_list(code);
        if(NULL == ptr)
         {printf("\n Node creation failed \n");
         return NULL;}
        ptr->next = NULL;
        head = curr = ptr;
        return ptr;
    }
    Also, please fix your horrible indentation. You have numerous 1 line while/if statements that look horrible:
    Code:
    /* Consider this */
        if(NULL == ptr)
         {printf("\n Node creation failed \n");
         return NULL;}
    /* vs this */
        if (NULL == ptr) {
            printf("\n Node creation failed\n");
            return NULL;
        }

  10. #10
    Registered User
    Join Date
    Dec 2014
    Posts
    7
    The horrible indentation is a by-product of copying the basis of the code from somewhere and then not making it consistent with what I use most of the times... I'll fix it up in a bit.
    nonpuz, that makes the function always return "Node creation failed"... But following your logic, I would also need to do those changes in the add_to_list function, correct?

  11. #11
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Quote Originally Posted by Phantaminum View Post
    So wait, you're saying I should make two structures? One to save the product info, which would be first in your code, and another to keep track of the structures I already have?
    Eh, on second thought, that's probably a bad idea. Idk, not all ideas I have are good.

    Edit : One thing about separating your data is that it would allow you to allocate your products and build a list in any way you wanted with it.
    Code:
    struct product_info *all_products = malloc(10 * sizeof(*all_products)); // allocate 10 products
    
    // fill product info...
    
    // build list out of product array in any way you wish
    You can also safely remove nodes in the list without removing data either.
    Last edited by MutantJohn; 12-30-2014 at 03:16 PM.

  12. #12
    Registered User
    Join Date
    Dec 2014
    Posts
    7
    And I'm one to talk about having good ideas... xD

    It works now, thank you all, sorry about the convoluted code and presentation, I just need to figure out a way to make the program not assign repeated product codes (if already has a product 0 and I ask it to add a new one, it will add a new product with the code 0), but I think I can manage that on my own.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 04-10-2012, 02:31 PM
  2. Double Linked Dynamic Lists Vs Unrolled Linked Lists
    By lantzvillian in forum C Programming
    Replies: 6
    Last Post: 02-14-2012, 01:07 PM
  3. Replies: 4
    Last Post: 05-01-2010, 10:19 PM
  4. Linked Lists error: m_deck undeclared identifier
    By marQade in forum C++ Programming
    Replies: 17
    Last Post: 05-16-2008, 02:15 PM
  5. question on linked lists(stack with linked lists)
    By dionys in forum C Programming
    Replies: 1
    Last Post: 06-02-2004, 11:08 AM