Problem z zapisaniem i wczytaniem listy rekordów z pliku.

0

Witam, mam problem z zapisaniem listy do pliku i jej wczytania. Rozmiar pliku się zwiększa ale jak wczytam listę to wyskakują jakieś krzaczki ;) Jakby ktoś mógł spojrzeć byłbym bardzo wdzięczny.

Pozdrawiam

typedef struct{
char imie[50];
char nazwisko[50];
char adres[50];
int  id;
}uzytkownik;

typedef struct{
uzytkownik user;
struct lista *next;}lista;

void add_u(uzytkownik temp)
{
 system("cls");
 lista *temp_u;
 temp_u=malloc (sizeof(lista));
 temp_u->next=NULL;
 if (head_u==NULL)
  {
    temp_u->user.id=1;
    head_u=temp_u;
  }
 else
  {
    lista*temp2_u;
    int last_id;
    temp2_u=head_u;
    while (temp2_u->next!=NULL)
     {
      temp2_u=temp2_u->next;
     }
      last_id=temp2_u->user.id;
      temp_u->user.id=last_id+1;
      temp2_u->next=temp_u;
   }
      strncpy(temp_u->user.imie, temp.imie, sizeof temp_u->user.imie-1);
      temp_u->user.imie[sizeof temp_u->user.imie-1] = 0;

      strncpy(temp_u->user.nazwisko, temp.nazwisko, sizeof temp_u->user.nazwisko-1);
      temp_u->user.nazwisko[sizeof temp_u->user.nazwisko-1] = 0;

      strncpy(temp_u->user.adres, temp.adres, sizeof temp_u->user.adres-1);
      temp_u->user.adres[sizeof temp_u->user.adres-1] = 0;

   }

void utworz_u()
{
  FILE *plik=NULL;
  if (plik=fopen("data", "rb"))
    { uzytkownik temp2;
      fpos_t l;
      int i;
      fseek(plik, 0, SEEK_END);
      fgetpos(plik, &l);
      l=l/sizeof(uzytkownik);
      fseek(plik, 0, 0);
      for (i=0; i<l; i++)
       {
        fread(temp2.imie, sizeof(char), 50, plik);
        fread(temp2.nazwisko, sizeof(char), 50, plik);
        fread(temp2.adres, sizeof(char), 50, plik);
        fread(&temp2.id, sizeof(int), 1, plik);
        add_u(temp2);
       }

    }
  else
   {  plik=fopen("data", "wb");}
      fclose(plik);
}

void zapisz_u()
{
  FILE *plik;
  lista*temp_u, *temp2_u;
  temp_u=head_u;

  if ((plik=fopen("data","w"))==NULL) // próba otwarcia pliku
       printf ("Blad otwarcia pliku");
   else{

        while (temp_u != NULL)
     {

       fwrite(&temp_u,sizeof(uzytkownik),1,plik);
       temp2_u=temp_u;
       temp_u = temp_u->next; /* przesuwamy head aż znajdziemy ostatni element */
     }
   }
}  
}
0
fwrite(&temp_u,sizeof(uzytkownik),1,plik);

czy tutaj nie ma błędu? (&temp_u)

0

gdzie w ogóle serializujesz dane do zapisu?

0
wojtala6 napisał(a)

	/* ... */

      strncpy(temp_u->user.imie, temp.imie, sizeof temp_u->user.imie-1);
      temp_u->user.imie[sizeof temp_u->user.imie-1] = 0;

      strncpy(temp_u->user.nazwisko, temp.nazwisko, sizeof temp_u->user.nazwisko-1);
      temp_u->user.nazwisko[sizeof temp_u->user.nazwisko-1] = 0;

      strncpy(temp_u->user.adres, temp.adres, sizeof temp_u->user.adres-1);
      temp_u->user.adres[sizeof temp_u->user.adres-1] = 0;

	/* ... */

      for (i=0; i<l; i++)
       {
        fread(temp2.imie, sizeof(char), 50, plik);
        fread(temp2.nazwisko, sizeof(char), 50, plik);
        fread(temp2.adres, sizeof(char), 50, plik);
        fread(&temp2.id, sizeof(int), 1, plik);
        add_u(temp2);
       }

	/* ... */

Ała, ała!
To kopiowanie znaków jest bez sensu. Szybciej będzie kopiować bloki pamięci. To samo tyczy się wczytywania - do bloku pamięci (zaalokowanej struktury) wczytaj 152 (o tym za moment) bajtów.
Wiesz o tym, że sizeof(int) jest inny na 32 i 64bit? Plik zapisany w systemie 32bit będzie błędnie odczytywany na 64bit (i na odwrót).

Co do Twojego pytania, jeśli masz krzaki, to znaczy że gdzieś nie trafiasz w swoją "strukturę" w pliku. Najpierw zobacz (w hexedytorze) co trafia na dysk i jeśli tam jest wszystko OK, zdiagnozuj od którego momentu zaczyna Ci krzaczyć i zobacz dlaczego (podejrzewam, że wpierniczasz się gdzieś w połowie tego inta).

Debuguj, debuguj, debuguj ;)

1

Zamiast tego ...

void utworz_u()
{
  FILE *plik=NULL;
  if (plik=fopen("data", "rb"))
    { uzytkownik temp2;
      fpos_t l;
      int i;
      fseek(plik, 0, SEEK_END);
      fgetpos(plik, &l);
      l=l/sizeof(uzytkownik);
      fseek(plik, 0, 0);
      for (i=0; i<l; i++)
       {
        fread(temp2.imie, sizeof(char), 50, plik);
        fread(temp2.nazwisko, sizeof(char), 50, plik);
        fread(temp2.adres, sizeof(char), 50, plik);
        fread(&temp2.id, sizeof(int), 1, plik);
        add_u(temp2);
       }
 
    }
  else
   {  plik=fopen("data", "wb");}
      fclose(plik);
}

chyba lepiej byloby...

void utworz_u()
{
  FILE *plik = fopen("data", "rb");
  if(!plik) {
      ShowMessage("Błąd otwarcia pliku");
      return;
  }
  BYTE users_count;            //<< ilu uzytkownikow zapisanych jest w pliku maks 255 mozesz dac int jesli chcesz wiecej
  fread((char*)&users_count, sizeof(BYTE),1, plik);
  
  uzytkownik tmpUser;
      
  for (i=0; i<users_count; i++)
  {
        fread((char*)&tmpUser,sizeof(uzytkownik),1,plik);
        add_u(tmpUser);
  }
}

a w zapisywaniu zamiast:

fwrite(&temp_u,sizeof(uzytkownik),1,plik);

//to.. 

fwrite((char*)&temp_u,sizeof(uzytkownik),1,plik);

zle rzutowales chyba

nie zapomnij dodac w funkcji zapisujacej na poczatku users_count ktorej wartosc bedzie zawierala ilosc userow zapisanych w pliku..

fwrite((char*)&users_count,sizeof(BYTE),1,plik);
0
kwasek2000 napisał(a)
zle rzutowales chyba

nie zapomnij dodac w funkcji zapisujacej na poczatku users_count ktorej wartosc bedzie zawierala ilosc userow zapisanych w pliku..

```cpp
fwrite((char*)&users_count,sizeof(BYTE),1,plik);

chodziło ci o takie coś ?

  temp_u=head_u;

 int users_count=0;

 /*while (temp_u!=NULL)
 {
   users_count++;
   temp_u=temp_u->next;
 }
 fwrite((char*)&users_count,sizeof(int),1,plik);

jeśli tak to ten kawałek kodu zawiesza program.

0

Nie lepiej uzyc tablicy albo vectora ?

tu podawalem przyklad
http://4programmers.net/Forum/C_i_C++/177254-nieszcesny_vertex

0

Nie bo tablica albo wektor to nie jest struktura dynamiczna a muszę mieć na strukturze dynamicznej.

void zapisz_u()
{
  FILE *plik;
  lista*temp_u, *temp2_u;
  temp_u=head_u;

  if ((plik=fopen("data","w"))==NULL) // próba otwarcia pliku
       printf ("Blad otwarcia pliku");
   else{

        while (temp_u != NULL)
     {

       fwrite((char*)&temp_u,sizeof(uzytkownik),1,plik);
       temp2_u=temp_u;
       temp_u = temp_u->next; 
     }hexedytorze
   }
   fclose(plik);
}

Wydaje mi się że zapisywanie nie działa dobrze bo jak otworzyłem ten plik w winhexie to wyskoczyło mi takie coś :
user image

0
wojtala6 napisał(a)

Nie bo tablica albo wektor to nie jest struktura dynamiczna a muszę mieć na strukturze dynamicznej.

void zapisz_u()
{
  FILE *plik;
  lista*temp_u, *temp2_u;
  temp_u=head_u;

  if ((plik=fopen("data","w"))==NULL) // próba otwarcia pliku
       printf ("Blad otwarcia pliku");
   else{

        while (temp_u != NULL)
     {

       fwrite((char*)&temp_u,sizeof(uzytkownik),1,plik);
       temp2_u=temp_u;
       temp_u = temp_u->next; 
     }hexedytorze
   }
   fclose(plik);
}

Wydaje mi się że zapisywanie nie działa dobrze bo jak otworzyłem ten plik w winhexie to wyskoczyło mi takie coś :

Jak na mój gust, to coś tu jest nie tak. Skąd bierzesz head_u w tej funkcji? To nie jest global. Jakim cudem Ci się to kompiluje? Jeśli to błąd w cytacie, to sprawdź na co wskazuje head_u. Być może na jakiś kosmos i jedziesz po złej pamięci, bo to co dostajesz w pliku nie wygląda nawet na część prawidłowych danych (zakładając, że listę populujesz prawidłowymi, czytelnymi danymi w ASCII).

0
Kumashiro napisał(a)

Jak na mój gust, to coś tu jest nie tak. Skąd bierzesz head_u w tej funkcji? To nie jest global. Jakim cudem Ci się to kompiluje? Jeśli to błąd w cytacie, to sprawdź na co wskazuje head_u. Być może na jakiś kosmos i jedziesz po złej pamięci, bo to co dostajesz w pliku nie wygląda nawet na część prawidłowych danych (zakładając, że listę populujesz prawidłowymi, czytelnymi danymi w ASCII).

head_u jest zadeklarowane globalnie

lista *head_u = NULL;
0
wojtala6 napisał(a)
Kumashiro napisał(a)

Jak na mój gust, to coś tu jest nie tak. Skąd bierzesz head_u w tej funkcji? To nie jest global. Jakim cudem Ci się to kompiluje? Jeśli to błąd w cytacie, to sprawdź na co wskazuje head_u. Być może na jakiś kosmos i jedziesz po złej pamięci, bo to co dostajesz w pliku nie wygląda nawet na część prawidłowych danych (zakładając, że listę populujesz prawidłowymi, czytelnymi danymi w ASCII).

head_u jest zadeklarowane globalnie

lista *head_u = NULL;

zastanawiam_sie znalazł Ci przyczynę błędu (hint: &temp_u jest typu lista**) . Że też SEGFAULTa nie dostałeś... :)

0

vector jest jak najbardziej dynamicznym pojemnikiem...

0
Kumashiro napisał(a)
wojtala6 napisał(a)
Kumashiro napisał(a)

Jak na mój gust, to coś tu jest nie tak. Skąd bierzesz head_u w tej funkcji? To nie jest global. Jakim cudem Ci się to kompiluje? Jeśli to błąd w cytacie, to sprawdź na co wskazuje head_u. Być może na jakiś kosmos i jedziesz po złej pamięci, bo to co dostajesz w pliku nie wygląda nawet na część prawidłowych danych (zakładając, że listę populujesz prawidłowymi, czytelnymi danymi w ASCII).

head_u jest zadeklarowane globalnie

lista *head_u = NULL;

zastanawiam_sie znalazł Ci przyczynę błędu (hint: &temp_u jest typu lista**) . Że też SEGFAULTa nie dostałeś... :)

Dzięki wielkie ;) Już działa, jak mówił zastanawiam_sie wystarczyło usunąć ten &. Sorry ale myślałem że błąd jest w czymś innym :) Dzięki wielkie za pomoc :)

0
kwasek2000 napisał(a)

vector jest jak najbardziej dynamicznym pojemnikiem...

jednak kod autora wątku wydaje się być napisany w C, więc zobacz sobie częścią jakiego języka jest stl.

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