CreaToN [ Generaďż˝ ]
Prosta baza danych w C.
Witam. Muszę napisać projekt, a że moja wiedza o programowaniu jest mała, więc szukam pomocy.
Tematem projektu jest program obsługi wypożyczalni płyt DVD. Program musi umożliwiać wykonanie:dodawania nowych płyt i klientów, wyszukiwanie, modyfikacja i usuwanie już istniejących oraz wypożyczanie. Bazy odczytywane i zapisywane do domyślnych plików.
Ponieważ program ma mieć nieskończenie wiele wpisów pomyślałem, żeby stworzyć listę łączoną, czyli, że każda struktura ma w sobie wskaźnik do następnej struktury. Napisałem więc część kodu odpowiadajacą dodawaniu nowych płyt i klientów i zapisywaniu ich do pliku.
I teraz zaczyna się problem, a raczej dwa. Po pierwsze, gdy dodaję filmy, plik w pewnym momencie kończy się (jest znak EOF) i dalej nic nie jest zapisywane. Nie wiem co z tym zrobić.
Druga sprawa dotyczy dalszej części programu. Chciałem zrobić osobną funkcję do wyszukiwania płyt, gdyż będzie ona potrzebna w większości dalszych funkcji. Jednak nie wiem jak otworzyć plik w którym mam zachowane dane na temat płyt. Starałem się korzystać z funkcji fread() ale nie działa, bo przy kompilacji wywala komunikat, ze xxx nie jest zadeklarowany. Jak przenieść wskaźniki z jednej funkcji do drugiej?
Poniżej fragment kodu odpowiadający dodawaniu plyt. Jak powinna wyglądać funkcja wczytująca wartości z pliku?
struct DVD
‹
char title[MAXT];
char category [MAXC];
float cost;
struct DVD *nast;
›;
int katalog()
‹
struct DVD *glowny = NULL; /*wskaznik glowny, potrzebny do odnalezienia pierwszego elementu*/
struct DVD *poprz, *biezacy;
char plyty[TYMCZ]; /*tymczasowa tablica do przechowywania danych. Z niej beda kopiowane dane do struktury*/
int n=0;
FILE *daneplyt;
daneplyt=fopen("plyty.c","a"); /*utworzenie pliku plyty.c do zapisywania struktur*/
(...) Tu znajduje się pętla while odpowiadająca za pobieranie danych do plyty[TYMCZ] i kopiowanie ich do struktur. Zmienna n jest zwiekszana o 1 po kazdym przejsciu pętli.
fwrite(glowny, sizeof(struct DVD), n, daneplyt);
fclose(daneplyt);
return(0);
›
Z góry dziękuję za pomoc.
Pozdrawiam.
Taikun. [ NINTENDO ]
tutaj: https://forumarchiwum.gry-online.pl/S043archiwum.asp?ID=4598146&N=1
:)
Scatterhead [ łapaj dzień ]
petla wczytujaca dane z pliku powinna zbudowac od poczatku liste jednokierunkowa. Musisz zadbac o to, żeby przy kazdym wczytaniu zainicjować dobrze wszystkie zmienne glowny, poprz, biezacy na NULL, a nastepnie dodawac kolejno elementy wczytane z listy.
Pierwszy element dodaje sie inny niz nastepne, poniewaz musisz ustawic znacznik glowny na ten element.
CreaToN [ Generaďż˝ ]
No tak, ale to są wskaźniki. Jak ja mam "przerzucić" te wskaźniki z funkcji katalog() do tej funkcji wyszukiwania, nazwijmy ją, szukaj()? Jeśli w funkcji szukaj() zadeklaruję struct DVD *glowny to będzie to inny wskaźnik niż ten w funkcji katalog(), gdyż one są lokalne i dotyczą tylko funkcji, w których są zadeklarowane.
Ja mam sam problem z wczytaniem, bo jeśli napiszę fread(glowny, sizeof(struct DVD), n, daneplyt) w funkcji szukaj() to choćbym nie wiem jak kombinował, to dopóki nie wczytam wskaźników i zmiennej n z katalog() to nic nie ruszy...
Cały mój problem polega na tym, że nie wiem jak wrzucić te wskaźniki do drugiej funkcji. I póki tego nie zrozumiem, to nic dalej nie pchnę.
Regis [ ]
Albo robisz je globalnie, albo przekazujesz jako parametr funkcji.
CreaToN [ Generaďż˝ ]
Regis -> No myślałem nad takim czymś, ale jak napisałem wyżej nie wiem jak przekazać te wskaźniki do innej funkcji. Mógłbyś jakoś rozwinąć swoją myśl?
Scatterhead [ łapaj dzień ]
Tak jak przekazujesz zwykłe parametry. Jako jego typ wpisz po prostu DVD*
void funkcja(DVD* parametr)
CreaToN [ Generaďż˝ ]
Ciągle mam problem z funkcją służącą do szukania w liście łączonej.
Zrezygnowałem z przekazywania wskaźników, bo chyba można zrobić to inaczej. Chciałbym spróbować to, tak jak radzi Scatterhead w [3]. Jeżeli się nie mylę, to można utworzyć listę od początku bez pobierania wskaźników lecz utworzenie nowych w tej funkcji.
Mam coś takiego:
int szukaj()
struct DVD *glowny=NULL;
struct DVD *poprz, *biezacy,
daneplyt = fopen("plyty.c", "r");
while( fread(glowny, sizeof(struct DVD), 1, daneplyt) == 1)
tutaj powinno być coś, co tworzy listę łączoną od początku.
fclose(daneplyt);
Przy kompilacji wyskakuje mi segmentation fault i jak zauważyłem dotyczy to funkcji fread(). Gdzie w fread() jest błąd?
Scatterhead [ łapaj dzień ]
Wyskakuje segmentation fault, ponieważ chcesz zapisać na wskazniku glowny, ktory jest NULL'em! Musisz najpierw stworzyc ten obiekt. Potem zapisać na niego, potem stworzyć nastepny, zapisac a potem je polaczyc wskaznikami.
CreaToN [ Generaďż˝ ]
Musisz najpierw stworzyc ten obiekt.
Nie rozumiem, jaki obiekt mam stworzyć?
To ma być zmienna typu struct DVD?
Scatterhead [ łapaj dzień ]
Tak, to ma być zmienna typu struct DVD stworzona komenda malloc z odpowiednimi parametrami
CreaToN [ Generaďż˝ ]
int szukaj()
struct DVD *glowny = NULL;
struct DVD *poprz, *biezacy;
struct DVD pierwszy;
daneplyt=fopen("plyty.c", "r");
while(fread(&pierwszy, sizeof(struct DVD), 1, daneplyt) == 1)
if(glowny == NULL)
glowny = &pierwszy;
biezacy = glowny;
else
biezacy=&pierwszy;
poprz->nast=biezacy;
biezacy -> nast= NULL;
poprz = biezacy;
printf("Film: %s \t Kategoria: %s \t cena: %0.2f\n", biezacy->title, biezacy->category, biezacy->cost);
fclose(daneplyt);
return(0);
Na ten moment mam coś takiego do odtworzenia listy. Za pierwszym razem pętla przechodzi zgodnie z oczekiwaniami, jednak przy wszystkich następnych wariuje i wyniki są losowe. printf() jest po to, aby zobaczyć czy lista się odtwarza. Domyślam się, że błąd jest w kawałku "else", ale strasznie się gubię w tych wskaźnikach więc w sumie nie wiem dokładnie co tam się kaszani. Prosiłbym o kolejną wskazówkę :)