Odwołwanie się do struktury w strukturze

0

Witam.

Moim zadaniem jest napisanie programu do przechowywania tytułów w bibliotece za pomocą listy 2-kierunkowej.
Mam problem z odwołaniem się do elementów struktury "data" zalokowanej w strukturze "Book".

 struct Book{
    bool stan;
    int id;
    char title[30];
    char aut_imie[20];
    char aut_nazw[20];
    char kategoria[20];
    struct data{
        int rok;
        int miesiac;
        int dzien;
    };
    char poz_imie[20];
    char poz_nazw[20];
    struct  Book *next;
    struct  Book *prev;
};

struct  Book *head=NULL; //poczatek listy
struct  Book *tmp=NULL; //poprzednio dodany
struct  Book *element=NULL; //aktualnie dodawany
struct  Book *cos; //element roboczy

struct Book *push(struct Book *head, char* aut_i, char* aut_n, char* tit, char* kat){
  if(head==NULL) {
    head=(struct Book*)malloc(sizeof(struct Book));
    tmp=(struct Book*)malloc(sizeof(struct Book));
    (*head).id=1000;
    (*head).stan=true;
    strcpy((*head).title, tit);
    strcpy((*head).aut_imie, aut_i);
    strcpy((*head).aut_nazw, aut_n);
    strcpy((*head).kategoria, kat);
    (*head).next=NULL;
    (*head).prev=NULL;
    tmp=head;
  } else {
    element=(struct Book*)malloc(sizeof(struct Book));
    (*element).id=(*tmp).id + 1;
    (*element).stan=true;
    strcpy((*element).title, tit);
    strcpy((*element).aut_imie, aut_i);
    strcpy((*element).aut_nazw, aut_n);
    strcpy((*element).kategoria, kat);
    (*element).next=NULL;
    (*tmp).next=element;
    (*element).prev=tmp;
    tmp=element;
  }
  return head;
}

Wiem, że do elementów Book odwołuje się poprzez przypisanie wskaźnika *cos do "koralika" listy i wpisanie cos->element, jednak nie mogę sobie poradzić z odwołaniem się do elementów data. Próbowałem dostać się tam poprzez cos->data.element, ale to jednak był głupi pomysł :)

0

Nie masz żadnej daty w obiekcie typu Book. Masz jedynie zadeklarowaną strukturę, którą to deklaracje możesz użyć np tak:

Book::data dzis;
dzis.rok=2015;

Dodatkowe uwagi:

  1. Jeżeli piszesz w C to nie możesz używać typu bool, zaś jeżeli piszesz w C++ to zamiast: struct Book *head=NULL; wystarczy Book *head=0;
  2. Rozdziel stworzenie nowego obiektu od podpięcia go do listy.
  3. Skoro masz w strukturze prev i next to ma sens również trzymać tail razem z head oraz warto ich trzymać w strukturze struct Library { Book *head,*tail; };
  4. Nie używaj polskich nazw (wyobraź sobie kod od chińskiego programisty).
  5. Dla zmiennych które nie mogą przyjmować ujemnych wartości używaj typów bez znakowych.
  6. Nie używaj zmiennych głośnych, tym bardziej zamiast zwykłych lokalnych.
  7. Rób funkcje proste i krótkie.
    W sumie powinno to wyglądać mniej więcej tak:
#include <stdio.h>
#include <stdlib.h>

typedef struct { unsigned short y,m,d; }Date;
typedef struct { char firstName[20],lastName[20]; } Person;
typedef struct
  {
    unsigned id;
    char title[30],category[20];
    Person author,lender; 
    Date data;
    int state;
  } Book;
typedef struct BookNode
  {
   Book book; 
   struct BookNode *prev,*next;
  } BookNode;
typedef struct { struct BookNode *head,*tail; } BookList;

void setDate(Date *date,unsigned short y,unsigned short m,unsigned short d)
  {
   date->y=y;
   date->m=m;
   date->d=d;
  }
  
void setPerson(Person *person,const char *firstName,const char *lastName)
  {
   /*...*/
  }
  
void setBook(Book *book,unsigned Id,const char *title,const char *category)
  {
   /*...*/
  }
 
BookNode *allocBookNode(BookNode *prev,BookNode *next)
  {
   BookNode *node;
   node=malloc(sizeof(BookNode));
   node->prev=prev;
   node->next=next;
   return node;
  }
  
Book *appendBook(BookList *lst)
  {
   BookNode *node;
   node=allocBookNode(lst->tail,NULL);
   if(lst->tail) lst->tail->next=node;
   else lst->head=node;
   lst->tail=node;
   return &(node->book);
  }
 
int main()
  {
   BookList lst={NULL,NULL};
   Book *book;

   book=appendBook(&lst);
   setBook(book,1,"Para w ruch","Fantasy");
   setPerson(&(book->author),"Terry","Pratchett");

   book=appendBook(&lst);
   setBook(book,2,"Blask fantastyczny","Fantasy");
   setPerson(&(book->author),"Terry","Pratchett");
   
   return 0;
  }
1

W Book masz tylko zdefiniowana strukturę data, natomiast nie ma żadnego obiektu tego typu. W Book stwórz obiekt i do niego się odwołuj.

0

@_13th_Dragon Kod rzeczywiście ładniejszy tylko teraz mam pytanie, jak powinien wyglądać kod w setPerson, bo nie wiem jak wskazać programowi czy chodzi o author, czy lender.

0

W setPerson() nie przyjmujesz się czy to autor czy wypożyczający.
W main() masz przykład jak znacjonalizować autora, jeżeli tobie nie wystarczy tego aby w analogiczny sposób postąpić z wypożyczającym, to wróć do czytanie jakiegoś kursu.

0

Dodam tylko, że zamiast:

 (*head).prev=NULL; 

możesz pisać:

head->prev=NULL;

1 użytkowników online, w tym zalogowanych: 0, gości: 1