Tworzenie listy jednokierunkowej w Strukturze.

Odpowiedz Nowy wątek
2019-01-11 23:07
0

Witam piszę projekt w którym muszę połączyć ze sobą studentów oraz wypożyczone przez nich książki. Chcę napisać funkcję która będzie tworzyła listę oraz zapisywała do niej dane. Jednakże nie wiem jak utworzyć wskaźniki aby operować po liście
Zamieszczam Fragment Kodu zawierający tworzoną funkcję oraz struktury.

typedef struct Book{ /// Struktura przechowujaca dane ksiazek
 
    int id;
    char author[15];
    char title[20];
    char year[4];
    struct BOOK *next;
 
}BOOK;
 
typedef struct Student{ ///Struktura przechowujaca dane studentów
 
    int id;
    char name[10];
    char surname[15];
    char email[20];
    char phone_num[9];
    BOOK *assigned;
 
}STUDENT;
 
.......
 
void assign_book(STUDENT *student_arr, BOOK *root){ /// PRZYPISANIE KSIAZEK STUDENTOM
 
FILE *a = fopen("a_test.txt","w");
BOOK *current = root;
int i,s_select,b_select,cell = 0;
 
printf("\nASSIGN BOOKS:");
//printf("\nPodaj id studenta:");
//scanf("%d",&s_select);
 
for(i=0;i<4;i++){
   // if(s_select == student_arr->id){
 
   current = root;
        printf("\n%s %s ma przeczytac:",student_arr->name,student_arr->surname);
        do{  ///WPISYWANIE KSIAZEK DLA 1 STUDENTA AZ DO WCISNIECIA 0
            scanf("%d",&b_select);
            while(current != NULL){ ///ITERACJA PO LISCIE KSIAZEK
                if(b_select == current->id){    ///POCZĄTEK LISTY WYPOZYCZONYCH KSIAZEK
 
                    student_arr->assigned = (BOOK*)malloc(sizeof(BOOK));  /**<======= W TEJ LINIJCE CHCIAŁBYM ZAMIENIĆ student_arr->assigned na *wskaźnik np. current_assigned_book
**/
                    strcpy(student_arr->assigned->author,current->author);
                    strcpy(student_arr->assigned->title,current->author);
                    strcpy(student_arr->assigned->year,current->author);
                    student_arr->assigned->id = current->id;
                    printf("sUCCES\n");
                    break;
                }
                else{
                    current = current->next;
                }
            }
 
        }while(b_select != 0 );
        //break;
    //}
    //else{
    student_arr++;
 }
 

To jest to co do tej pory udało mi się napisać.
W tym momencie program tylko odczytuje wartość przechodzi do następnego studenta i zastępuje poprzednio wprowadzoną książkę, a chciałbym żeby dopóki
nie wprowadzi się 0 funkcja dodawała książkę do listy jednokierunkowej która zawiera książki danego studenta i po wprowadzeniu 0 przechodziła do kolejnego studenta. Tylko nie wiem jak zorganizować wskaźniki aby taką listę utworzyć, jeżeli ktoś mógłby mi pomóc byłbym wdzięczny.
W kodzie zaznaczyłem o co mniej więcej chodzi oraz potrzebowałbym wskaźnika wskazującego na pierwszy element z listy oraz wskaźnika pomocniczego.
Nie jestem pewien czy każdy zrozumie o co mi chodzi, jeśli są jakieś wątpliwości to postaram się dokładniej wyjaśnić

nie musisz używać strcpy. w C możesz używać operatora = dla struktur. W każdym razie w C99 można, na szanującch się, współczesnych kompilatorach powinno działać. - elwis 2019-01-12 00:07
Właśnie, na współczesnych kompilatorach, ale osoba prowadząca Pracownie u mnie na studiach dalej siedzi gdzieś w standardzie C90 więc better to be safe than sorry. - NightSun221 2019-01-12 00:23
to w takim razie możesz tak: memcpy(cel, &zrodlo, sizeof(zrodlo)) - elwis 2019-01-12 20:04

Pozostało 580 znaków

2019-01-11 23:39
1

Ja to bym w ogole zrobil strukture zawierajaca tylko wskaznik na ksiazke i wskaznik na kolejny element zamiast kopiowac calutka ksiazke do kazdej listy

Pozostało 580 znaków

2019-01-11 23:57
0
stivens napisał(a):

Ja to bym w ogole zrobil strukture zawierajaca tylko wskaznik na ksiazke i wskaznik na kolejny element zamiast kopiowac calutka ksiazke do kazdej listy

typedef struct Assigned{
 
BOOK* assigned_book;
struct Assigned *next;
 
}ASIGN_BOOK;
 

O to chodzi??

Pozostało 580 znaków

2019-01-12 00:30
0
NightSun221 napisał(a):
stivens napisał(a):

Ja to bym w ogole zrobil strukture zawierajaca tylko wskaznik na ksiazke i wskaznik na kolejny element zamiast kopiowac calutka ksiazke do kazdej listy

typedef struct Assigned{
 
BOOK* assigned_book;
struct Assigned *next;
 
}ASIGN_BOOK;
 

O to chodzi??

void assign_book(STUDENT *student_arr, BOOK *root){ /// PRZYPISANIE KSIAZEK STUDENTOM
 
FILE *a = fopen("a_test.txt","w");
BOOK *current = root;
ASIGN_BOOK *current_asgn = NULL;
ASIGN_BOOK *root_asgn = NULL;
ASIGN_BOOK *ptr_asgn = NULL;
int i,b_select;
 
printf("\nASSIGN BOOKS:");
 
    for(i=0;i<4;i++){
            current = root;
            printf("\n%s %s ma przeczytac: ",student_arr->name,student_arr->surname);
        do{
            current = root;
            printf("\nPodaj id ksiazki");
            scanf("%d",&b_select);
            while(current != NULL){
                if(current->id == b_select){
                current_asgn = (ASIGN_BOOK*)malloc(sizeof(ASIGN_BOOK));
                current_asgn->assigned_book = current;
                current_asgn->next = NULL;
                printf("Succes");
 
                if(root_asgn == NULL){
                    root_asgn = current_asgn;
                }
                else{
                    ptr_asgn = root_asgn;
                    while(ptr_asgn->next != NULL)
                        ptr_asgn = ptr_asgn->next;
                    ptr_asgn->next = current;
                }
                break;
                }
                else{
                    current = current->next;
                }
            }
        }while(b_select != 0);
    student_arr++;
    }
}

Zrobiłem to w ten sposób ale po wczytaniu 3 wartości nie ważne czy po 1 książce dla każdego czy 3 od razu program się wysypuje. Sorry jeśli piszę głupoty ale you`ve got to start somewhere.

Pozostało 580 znaków

2019-01-12 12:10
1

Przeczytalem to dwa razy i nie jestem pewien co autor mial na mysli a ze nie mam sily tego analizowac to napisze po prostu jak to mogloby wygladac

Najpierw struktury

typedef struct book_t {
    int id;
    char author[20];
    char title[30];
    char year[4];
} Book;
 
typedef struct book_list_t {
    struct book_list_t *next;
    Book *book;
} BookList;
 
typedef struct student_t {
    int id;
    char name[15];
    char surname[15];
    char email[30];
    char phone_num[9];
    BookList *books;
} Student;
 
BookList *create_booklist_node(Book *book)
{
    BookList *bl = malloc(sizeof(BookList));
    bl->next = NULL;
    bl->book = book;
 
    return bl;
}

I teraz zeby dopisac studentowi jakas ksiazke to robimy nowy element listy, ktory wskazuje na odpowiednia ksiazke a next wskazuje na jego aktualna liste ksiazek. Teraz wystarczy tylko zeby student->books wskazywalo na nowa liste, ktora wlasnie utworzylismy

 
int assign_book_to_student(int book_id, Student *student, BookList *list_of_all_books)
{
    BookList *new_node = NULL;
 
    while (list_of_all_books != NULL) {
        if (list_of_all_books->book->id == book_id) {
            new_node = create_booklist_node(list_of_all_books->book);
            break;
        }
        list_of_all_books = list_of_all_books->next;
    }
 
    if (new_node == NULL) {
        return 1;
    } else {
        new_node->next = student->books;
        student->books = new_node;
 
        return 0;
    }
}
Ok. rozumiem praktycznie wszystko,tylko czym jest ten 3 parametr w funkcji assign_books_to_student?? - NightSun221 2019-01-12 16:10
Lista wszystkich ksiazek. Mozesz tam bezposrednio ksiazke przesylac ale jakos ja trzeba zidentyfikowac i tak - stivens 2019-01-12 16:33

Pozostało 580 znaków

2019-01-12 19:06
0

A więc tak udało mi się utworzyć funkcję przypisującą Studentom książki.

void assign_book(STUDENT *student_arr, BOOK *root){ /// PRZYPISANIE KSIAZEK STUDENTOM
 
BOOK *current_book = root;
ListBooks *current = NULL;
ListBooks *head = NULL;
ListBooks *ptr = NULL;
int i,b_select,count = 0;
 
do{
    //current_book = root;
    printf("\nPodaj id ksiazki:");
    scanf("%d",&b_select);
 
    while(current_book != NULL && b_select != 0){
        if(b_select == current_book->id){
 
            current = (ListBooks*)malloc(sizeof(ListBooks));
 
            current->count = count;
            current->Book = current_book;
            current->next = NULL;
 
            count++;
 
        if(head == NULL){
 
        head = current;
        }else{
 
            ptr = head;
            while(ptr->next != NULL)
                ptr = ptr->next;
            ptr->next = current;
            }
        break;
        }else{
        current_book = current_book->next;
        }
    }
 
}while(b_select != 0);
}

Jednak mam problem z wyświetleniem jej gdyż do funkcji

void print_assigned_books(ListBooks *list_of_assigned_books){
 
ListBooks *current = list_of_assigned_books;
 
printf("%s",current->Book->title);
 
}

Chcę podać wskaźnik do listy np. 2 studenta ale nie wiem jak to zrobić. Moja funkcja main wygląda tak:

STUDENT S_ARRAY[20]; ///Lista 20 studentów
 
ListBooks* Ksiazki = S_ARRAY[2]->books; // Próba stworzenia wskaźnika do listy książek 2 studenta
 
print_assigned_books(Ksiazki);
 

W tej funkcji dostaję błąd jestem pewien że źle próbuje przypisać wskaźnik.Pytanie tylko jak to zrobić aby to zadziałało. Struktura do której próbuje się odwołać wygląda tak:

typedef struct Student{ ///Struktura przechowujaca dane studentów
 
    int id;
    char name[10];
    char surname[15];
    char email[20];
    char phone_num[9];
    ListBooks *books;
 
}STUDENT;
A jaki blad konkretnie? - stivens 2019-01-12 19:22
Moze S_ARRAY[2].books - stivens 2019-01-12 19:23
Program received signal SIGSEGV, Segmentation fault. In ungetwc () (C:\Windows\System32\msvcrt.dll) coś takiego mi wywala po użyciu S_ARRAY[2].books - NightSun221 2019-01-12 22:56

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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