Problem z programem zapisującym i odczytującym dane z pliku.

Odpowiedz Nowy wątek
2011-10-04 11:15
0

O to fragment programu. Zapisywanie działa póki co bez problemu. Wczytywanie uprościłem na razie do minimum (wyrzuciłem pętlę), a i tak nie działa jak powinno.

struct wezel{
  char nazwisko[20];
  int wiek;
  struct wezel *nast, *pop;
};

void wstawP(struct wezel *nowy){

  nowy->nast = wykaz;
  if (wykaz!=NULL) wykaz->pop = nowy;
  nowy->pop = NULL;
  wykaz = nowy;

}

void odczytaj(){
 FILE * pFile;
  pFile = fopen ("myfile.txt","r");
   struct wezel *w;

   fscanf(pFile, "%s %d", w->nazwisko,&w->wiek);

   fclose (pFile);
  printf ("\n Dane z pliku zostały wczytane. \n");
wstawP(w);
}

Mam plik myfile.txt o treści:

ddd 22

Po załadowaniu pliku i użyciu drukowania wychodzi mi coś takiego:

d
spacja 22

Jakieś rady?;)
Dlaczego omija tekst przed liczbą? %s jest chyba w porządku.

edytowany 2x, ostatnio: madmike, 2011-10-04 19:18

Pozostało 580 znaków

2011-10-04 11:23
alex
0

jakiego drukowania - nigdzie nie pokazujesz wypisywania zawartości pliku.

Pozostało 580 znaków

2011-10-04 12:01
0

Przepraszam. Mój błąd. Oto cały program:

 #include <stdio.h> 
 #include <stdlib.h> 
 #include <string.h> 

 struct wezel{ 
 char nazwisko[20]; 
 int wiek; 
 struct wezel *nast, *pop; 
 }; 

 int ilosc; 
 int rozmWezla = sizeof(struct wezel); 
 struct wezel *wykaz=NULL; 

 void czekaj(){ 
 printf("wcisnij ENTER"); getchar(); 
 } 

 void wstawP(struct wezel *nowy){ 

 nowy->nast = wykaz; 
 if (wykaz!=NULL) wykaz->pop = nowy; 
 nowy->pop = NULL; 
 wykaz = nowy; 

 } 

 void wstaw(){ 
 struct wezel *w = (struct wezel *)malloc(rozmWezla); 
 printf("nazwisko, wiek: "); 
 scanf("%s%d",w->nazwisko,&w->wiek); 
 wstawP(w); 
 } 

 void drukuj(){ 
 struct wezel *w; 
 for (w=wykaz;w!=NULL;w=w->nast) 
 printf("%s %d \n", w->nazwisko,w->wiek); 
 czekaj(); 
 } 

void odczytaj(){
  FILE * pFile;
   pFile = fopen ("myfile.txt","r");
    struct wezel *w;

    fscanf(pFile, "%s %d", w->nazwisko,&w->wiek);

    fclose (pFile);
   printf ("\n Dane z pliku zostały wczytane. \n");
 wstawP(w);
 }

 void zapisz(){ 
 FILE * pFile; 
 pFile = fopen ("myfile.txt","a"); 
 struct wezel *w; 
 for (w=wykaz;w!=NULL;w=w->nast) 
 { 
 fprintf(pFile, "%s %d \n", w->nazwisko,w->wiek); 
 } 
 fclose (pFile); 
 }

 main(){ 
 char z[100]; 
 do { 
 printf("\n\n w - wstaw"); 
 printf("\n d - drukuj"); 
 printf("\n z - zapisz"); 
 printf("\n k - koniec"); 
 printf("\n wybor: "); 
 fgets(z,100,stdin); 
 switch(z[0]){ 
 case 'w' : wstaw(); break; 
 case 'd' : drukuj(); break; 
 case 'z' : zapisz(); break; 
 } 
 }while(z[0]!='k'); 

 } 

Mój obecny problem dotyczy void odczytaj, która nie odczytuje danych z pliku tak jak powinna.

edytowany 1x, ostatnio: madmike, 2011-10-04 19:18

Pozostało 580 znaków

2011-10-04 12:12
alex
0

to to przyjrzyj się dokładnie linijce:
fscanf(pFile, "%s %d",
w->nazwisko,
&w->wiek);

widzisz ten znak &

przy wieku jest a przy nazwisko go nie ma?

Ta linijka jest poprawna bo w->nazwisko jest rzutowane niejawnie na wskaźnik - Shalom 2011-10-04 13:58

Pozostało 580 znaków

2011-10-04 12:20
0

alex - fscanf jest dobry.

Ja nie widzę tutaj alokowania pamięci na węzeł.

Pozostało 580 znaków

2011-10-04 13:47
0

Alokowania pamięci na węzeł?
struct wezel *w; nie wystarczy? Wystarcza przy zapisz void.

To jest tylko utworzenie wskaźnika który pokazuje w jakieś miejsce w pamięci. Nie alokujesz to wcale żadnej pamięci... - Shalom 2011-10-04 13:57

Pozostało 580 znaków

2011-10-04 16:54
0

Przy zapisie ustawiasz wskaźnik na wcześniej zaalokowane stryktury, przy odczycie nie. Tak poza tym, to u mnie działa.

Pozostało 580 znaków

2011-10-04 17:16
0

Nie do końca rozumiem. Czyli co muszę zmienić?

Pozostało 580 znaków

2011-10-04 17:29

Shalom ma rację: mamy wiszący wskaźnik "wezel w" i brakuje czegoś co jest w funkcji wstaw():
struct wezel
w = (struct wezel *)malloc(rozmWezla);

Dopiero wtedy można przypisywac cokolwiek do w->nazwisko i w->wiek.

Pozostało 580 znaków

2011-10-04 18:37
0

Tego brakowało. Teraz działa bez zarzutów. A więc czas dodać pętle, żeby wczytywało więcej danych z jednego pliku.
I tu kolejny problem. Pętla użyta do zapisywania do pliku nie działa już przy odczytywanie.
Wyskakuje błąd: Naruszenie ochrony pamięci.

 void odczytaj(){
 FILE * pFile;
  pFile = fopen ("myfile.txt","r");
   struct wezel *w = (struct wezel *)malloc(rozmWezla); 
 for  (w=wykaz;w!=NULL;w=w->nast)
{
   fscanf(pFile, "%s%d \n", w->nazwisko,&w->wiek);
}
   fclose (pFile);
  printf ("\n Dane z pliku zostały wczytane. \n");
wstawP(w);
}

Gdy zrobię taką zmianę, to nie wyrzuca błędu, ale i tak wczytuje tylko pierwszą linijkę z pliku txt :/

void odczytaj(){
 FILE * pFile;
  pFile = fopen ("myfile.txt","r");

   struct wezel *w = (struct wezel *)malloc(rozmWezla); 
wstawP(w);
 for  (w=wykaz;w!=NULL;w=w->nast)
{
   fscanf(pFile, "%s%d \n", w->nazwisko,&w->wiek);
}
   fclose (pFile);
  printf ("\n Dane z pliku zostały wczytane. \n");

} 
edytowany 2x, ostatnio: madmike, 2011-10-04 19:19
Wstawiaj kod w znaczniki: <code=c>//tutaj kod</code> - madmike 2011-10-04 19:19

Pozostało 580 znaków

2011-10-04 19:31
0

malloc alokuje pamięć, ale jej nie inicjuje - są tam śmieci. To znaczy, że po zaalokowaniu pamięci dla "wezel* w", pole w->next wskazuje na dowolny obszar pamięci do którego chcesz przypisać dane w drugim obiegu pętli. Czyli zmiana powinna polegać na tym, że:

  1. najpierw alokujesz pamięć dla w->next
  2. dopiero potem czytasz z pliku i zapisujesz odczytane dane do w->next->nazwisko i w->next->wiek

Jeszcze jedno: cała pętla for jest bez sensu. Powinieneś w pętli czytać dane w pliku - czyli koniec pliku byłby dla ciebie końcem pętli i przy każdym jej obiegu inicjujesz pamięć dla w->next i zapisujesz do w->next->nazwisko i w->next->wiek.

edytowany 2x, ostatnio: Tomek2, 2011-10-04 19:43

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