C struktury i zapis do pliku

0

Witam mam pewien problem niestety wydaję mi się z dość podstawowymi rzeczami ale nie mogę do tego dojść i chciałbym żeby ktoś mnie trochę nakierował bo wydaję mi się,że istnieje dużo możliwych opcji.
Mam strukturę np:

struct baza{
char nazwa[200];
double ilosc;
}rekord [10]; //nie jestem pewien czy to dobre rozwiązanie tworzyć strukturę tablic(lub na odwrót) jednak nie wiem do końca jak to zrobić na listach, bo w tym wypadku wydaję mi się to takie najbardziej logiczne,że każda pozycja ma swój numer ale to chyba tak nie działa

 

Teraz chciałbym te rekordy zapisywać do pliku binarnie fwrite(ilosc[1].nazwa,sizeof(ilosc[1].nazwa),1,fp) lub po prostu fwrite(rekord,sizeof(rekord),1,fp). Jeszcze pytanie co do zapisu binarnego spotkałem się z formatem pliku np fp.dat a nie .txt czym to się różni?

Tutaj pojawia się problem gdyż stringi zapisują się bez problemu, double niestety już nie, trzeba konwertować do stringa?
Mam funkcję do pobierania liczb z tym,że nie wiem jak zrobić żeby zwracała ona ciąg znaków.

Podsumowując chciałbym zrobić taką nie duża bazę danych i było by miło jak ktoś dał by kilka wskazówek,zaczynając od tego jak najlepiej zrobić tą strukturę oraz jak skutecznie zapisywać to do pliku.

0

poprawniej tak:
int zapisano=fwrite(rekord,sizeof(struct baza),IleZapisac,fp);
Wtedy zapisano powinno być równe IleZapisac, jeżeli nie to znaczy jakiś błąd zapisu.
Rozszerzenie plików w windowsach jest tylko po to aby skojarzyć rozszerzenie z jakimś programem, raczej nie powinieneś dawać rozszerzenie .txt bo użytkownicy będą próbować edytować ten plik notepadem.

... double niestety już nie, trzeba konwertować do stringa?
Zastanów się chcesz binarnie czy jednak tekstowo?
Binarnie odczytujesz tak samo:
int wczytano=fread(rekord,sizeof(struct baza),sizeof(record)/sizeof(*record),fp);
Wtedy wczytano powinno być równe tyle ile zapisano ale nie więcej niż sizeof(record)/sizeof(*record) czyli tyle ile zadeklarowałeś (w twoim przykładzie 10).
Przy zapisie tekstowym zapis będzie zajmować znacznie więcej wierszy, zaś odczyt ... tu musisz uwzględnić że użytkownik może nabroić za pomocą notepada i różne cuda mogą się dziać. Więc odczyt tekstowy to sprawdzenie na sprawdzeniu :D

... jak najlepiej zrobić ...
A powiedz mi co jest lepsze lody czy schabowy? Tu tak samo, wszystko zależy. Gdyby istniał jeden najlepszy wariant to tylko ten wariant istniałby.

0
  1. Do trybu binarnego użyj nazwy z rozszerzeniem *.DAT

  2. Ale to nie ma znaczenia w Twoim przypadku, znaczenie ma jak użyłeś funkcji fopen ? http://www.cplusplus.com/reference/cstdio/fopen/

  3. Sprecyzuj zdanie:
    "Tutaj pojawia się problem gdyż stringi zapisują się bez problemu, double niestety już nie, trzeba konwertować do stringa?"
    Co to znaczy że double się nie zapisuje bez problemu?

  • otwiera się w Notepad z krzaczkami? (sytuacja poprawna)
  • odczyt się wywala? (jak?)
  • odczytane wartości nie zgadzają się z zapisanymi? (jak?)
0

Dzięki za odpowiedzi wydaję mi się,że już zapisuję poprawnie. Jednak gorzej z tym operowaniem wewnątrz pliku,załóżmy,że zapisze parę rekordów rekord[0],rekord[1],rekord[2] i chcę wczytać tylko rekord[1] i tutaj pojawia się pewien problem,domyślam się,że muszę ustawić wskaźnik w miejscu rekordu[1] tylko nie wiem zbytnio jak próbowałem fseek ale nie wiem jak obliczyć rozmiar tych rekordów nad tym,który chce wczytać.
Przy rekordzie[0] nie ma problemu bo jest on pierwszy więc nic nie trzeba przesuwać.

Jest to dla mnie o tyle istotne ponieważ wydaję mi się,że najrozsądniej potem to wykorzystać do usuwania/szukania/edytowania rekordów

0

fseek(fp,Nr*sizeof(record),SEEK_SET);

0

Nie chcąc zakładać nowego tematu napisze tutaj.Mam cały czas z tym problem ponieważ chciałbym zrobić to w ten sposób,że mam stukture rekord[i] i powiedzmy rekordy o i=0,i=2 są użyte a rekord o i=1 usunąłem i przy następnym dodawaniu chciałbym go wykorzystać i zapisać w jego miejsce. Próbowałem robić w ten sposób,że kiedy jakiś rekord zwraca NULL tzn,że jest pusty zapisywałem na jego miejsce. ale NULL jest zwracane również wtedy kiedy jest jakiś inny problem z plikiem także to odpada.

Wydaję mi się,że trzeba by było zapełnić całą strukturę dla wszyskich [i] jakimiś danymi np. 0 i wtedy szukać właśnie tych struktur, jednak prosiłbym o pomoc bo mi to nie chce zacząć działać

0
  1. Podczas działania programu musisz pamiętać Ilość rekordów w pliku.
  2. Przy usuwaniu wymień zawartość rekordu z ostatnim, zmniejsz zapamiętaną Ilość rekordów w pliku.
  3. Przed wyjściem z programu, zamykasz plik, przemianowujesz go na inną nazwę, otwierasz jako pusty przepisujesz z kopii rekord po rekordzie, usuwasz kopie.
0

Teoretycznie rozumiem ale ciężej to wprowadzić w życie, tak jak wcześniej pisałem mam tablicę struktur i chciałbym szukać pierwszego wolnego numeru robiłem to w ten sposób

 
int w=100;
fp = fopen("dane.dat","rb");

    int wczytaj;                                       
for(Nr=0;Nr<W;Nr++){       
    fseek(fp,Numer*sizeof(rekord[Numer]),SEEK_SET);
    wczyta =  fread(&rekord[Nr],sizeof(rekord[Nr]),1,plik);
if(wczytaj==0)break;

            }
            fclose(plik);


i jak to poprawić żeby własnie tak jak napisałeś program pamiętał tą ilość rekordów.Bo tutaj chciałem żeby zwracał własnie ten pierwszy wolny numer jednak to kryteriumw którym ma szukać rekordu który zwraca NULL średnio działa.Więc myślałem żeby to zastąpić np. właśnie tymi zerami.

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