2

I have a struct named book and a list linked to struct book. I must add books to my book list and then to display the list. I created a function "printBList" to print at screen the information of my list. But i do something wrong when I am trying to print the book.id and the program stops to responding. I believe that the lines "book *b=head->book;" and "printf("book ID%d\n", b->id);" are wrong, but I can not find how I have to write then right. Could someone help me?

#include <stdio.h>
#include <stdlib.h>

#define MAXSTRING 100
#define MAXREVIEWS 100

typedef  enum genres{
    fiction, 
    sientific,
    politics
};

typedef struct
{
    char author[MAXSTRING];
    char title[MAXSTRING];
    enum genres genre;
    int id;
    char reviews[MAXREVIEWS][MAXSTRING];
} book;


typedef struct list 
{
    int BookID;
    struct list * next;
    struct book * book;
} BList;


void printBList(BList * head) 
{
    BList * current = head;
    book *b=head->book;

    while (current != NULL) {
        printf("List ID:: %d\n", current->BookID);
        printf("book ID%d\n", b->id);
        //printf("%d\n", current->BookID);        
        current = current->next;
    }
}


int main()
{
    BList * head = NULL;
    head = malloc(sizeof(BList));
    if (head == NULL) {
        return 1;
    }

    book b={"author 1","title 1",1,22,"review 1"};  

    head->next = NULL;
    head = malloc(sizeof(BList));

    head->BookID = 1;
    head->next = malloc(sizeof(BList)); 
    head->next->BookID = 24;
    head->next->book;
    head->next->next = NULL;

    printBList(head);
    return 0;
}
gsamaras
  • 71,951
  • 46
  • 188
  • 305
evangelia
  • 53
  • 6
  • 1
    `printf("book ID%d\n", b->id);` --> `printf("book ID%d\n", current->book->id);` – BLUEPIXY May 29 '17 at 21:12
  • fix like [this](http://ideone.com/WyzypY) – BLUEPIXY May 29 '17 at 21:23
  • The `typedef enum genres { … };` is pointless; it doesn't name a type. A good compiler would warn about that. You could have intended `typedef enum genres { … } genres;` — that makes sense. You should make sure you know how to turn on 'maximum' warnings from your compiler, and you should heed every warning it gives you. Remember, the compiler knows a lot more about C than you do as yet — and it doesn't warn unless it thinks there's a bug in your code. – Jonathan Leffler May 29 '17 at 21:57

1 Answers1

5

The problem is in the way you print the list, here:

while (current != NULL) {
    printf("List ID:: %d\n", current->BookID);
    printf("book ID%d\n", b->id); // <-- HERE
    current = current->next;
}

You work with current, but you try to print b, which is fixed.

You probably meant to say this:

printf("book ID%d\n", current->book->id);

There more issues though:

Moreover, you meant to write:

typedef struct book {
   ..
} book;

You are accessing next of head, before creating the space for head, here:

head->next = NULL;
head = malloc(sizeof(BList));

So change it to:

head = malloc(sizeof(BList));
head->next = NULL;

Moreover, this line:

head->next->book;

does nothing.

Next, you should check your warnings:

Georgioss-MacBook-Pro:~ gsamaras$ gcc -Wall main.c 
main.c:7:1: warning: typedef requires a name [-Wmissing-declarations]
typedef  enum genres{
^~~~~~~
main.c:34:11: warning: incompatible pointer types initializing 'book *' with an
      expression of type 'struct book *' [-Wincompatible-pointer-types]
    book *b=head->book;
          ^ ~~~~~~~~~~
main.c:53:39: warning: suggest braces around initialization of subobject
      [-Wmissing-braces]
    book b={"author 1","title 1",1,22,"review 1"};  
                                      ^~~~~~~~~~
                                      {         }
main.c:61:17: warning: expression result unused [-Wunused-value]
    head->next->book;
    ~~~~~~~~~~  ^~~~
main.c:53:10: warning: unused variable 'b' [-Wunused-variable]
    book b={"author 1","title 1",1,22,"review 1"};  
         ^
5 warnings generated.

When you typedef something, you need to give a synonym, so do this for your enumeration:

typedef  enum genres{
  ..
} genres;

Since reviews is a 2D array, you can do this instead:

book b={"author 1","title 1",1,22, {"review 1"} }; 

Moreover, do not use magic numbers, like 1 in this case, since you have an enum for this purpose.


Then, I changed your main() a bit, to add the same book twice, with a different List ID. Putting everything together, we get:

#include <stdio.h>
#include <stdlib.h>

#define MAXSTRING 100
#define MAXREVIEWS 100

typedef  enum genres{
    fiction, 
    sientific,
    politics
} genres;

typedef struct book
{
    char author[MAXSTRING];
    char title[MAXSTRING];
    enum genres genre;
    int id;
    char reviews[MAXREVIEWS][MAXSTRING];
} book;


typedef struct list 
{
    int BookID;
    struct list * next;
    struct book * book;
} BList;


void printBList(BList * head) 
{
    BList * current = head;

    while (current != NULL) {
        printf("List ID:: %d\n", current->BookID);
        printf("book ID%d\n", current->book->id);
        current = current->next;
    }
}


int main()
{
    BList * head = NULL;
    head = malloc(sizeof(BList));
    if (head == NULL) {
        return 1;
    }

    book b={"author 1","title 1", sientific ,22,{"review 1"}};  

    head->next = NULL;
    head->BookID = 1;
    head->book = &b;

    head->next = malloc(sizeof(BList)); 
    head->next->BookID = 24;
    head->next->book = &b;
    head->next->next = NULL;

    printBList(head);
    return 0;
}

Output:

Georgioss-MacBook-Pro:~ gsamaras$ gcc -Wall main.c 
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out 
List ID:: 1
book ID22
List ID:: 24
book ID22

PS:

  1. Don't forget to de-allocate the space you allocated dynamically. Do this with free().
  2. It's a good practice to check if malloc() was successful, by checking if its return value was NULL (meaning failure). Read more in How detect malloc failure?
gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • hello! Thank you so much for the speedy reply! I made the change you suggest, but the program still stops responding. – evangelia May 29 '17 at 21:16
  • @evangelia you did a good attempt, thus I updated my answer, with full working code. Hope that helps! =) – gsamaras May 29 '17 at 21:27
  • 1
    Only other tweak would be to *always validate* your memory allocations, (e.g. `if (!(head = malloc(sizeof(BList)))) {...handle error...}`) – David C. Rankin May 29 '17 at 21:50