Problem z plikiem rekordowym.

0

Witam, otóż na lekcję muszę dostarczyć projekt mój bazę danych i chodzi o to, że działa faktycznie, ale to co zapisuję się w pliku jest po prostu dziwne ;/
Kod :

program baza_danych;
uses CRT;

type
    dane = record
         imie: string[15];
         nazwisko: string[20];
         wiek: integer;
         dochody: real;
    end;

var
   plik: file of dane;
   nazwa_bazy: string;
   ileosob: integer;
   i, j: integer;
   baza: array[1..20] of dane;


procedure menu;
begin
     writeln('----------Witaj w szkolnej bazie danych----------');
     writeln('1 - Wprowadzanie nazwy bazy danych.');
     writeln('2 - Wpisywanie danych uczniowskich do bazy danych.');
     writeln('3 - Wyswietlanie poszczegolnych uczniow z bazy danych.');
     writeln('4 - Wyswietlanie wszystkich uczniow z bazy danych od pozycji pierwszej do x.');
end;

procedure poczatek;
begin
     write('Podaj nazwe pliku: ');
     readln(nazwa_bazy);
end;

procedure wprowadzanie;
begin
     repeat
     write('Podaj ile osob chcesz wprowadzic do bazy (max. 20): ');
     readln(ileosob);
     writeln;
     until (ileosob<=20) and (ileosob>=1);
     for i:=1 to ileosob do
     begin
          write('Podaj ',i,' imie: ');
          readln(baza[i].imie);
          write('Podaj ',i,' nazwisko: ');
          readln(baza[i].nazwisko);
          write('Podaj wiek ',i,' osoby: ');
          readln(baza[i].wiek);
          write('Podaj dochody ',i,' osoby: ');
          readln(baza[i].dochody);
          writeln('----------------------------------');
     end;
 end;
procedure wyswietl;
begin
     j:=0;
     writeln('Podaj ile osob chcesz wyszukac poprzez wpisywanie numerow: ');
     readln(j);
     for i:=0 to j do
     begin
          writeln('Podaj numer osoby ktora chcesz zobaczyc dane: ');
          readln(i);
          writeln('Imie ',i,' osoby to: ',baza[i].imie);
          writeln('Nazwisko ',i,' osoby to: ',baza[i].nazwisko);
          writeln('Wiek ',i,' osoby to: ',baza[i].wiek);
          writeln('Dochody ',i,' osoby to: ',baza[i].dochody:8:2);
          writeln('--------------------------------------------');
          writeln;
     end;
end;

procedure wyswietl_wiecej;
begin
     j:=0;
     writeln('Podaj ile pierwszych osob chcesz dane zobaczyc: ');
     readln(j);
     writeln;
     for i:=1 to j do
     begin
          writeln('Imie ',i,': ',baza[i].imie);
          writeln('Nazwisko ',i,': ',baza[i].nazwisko);
          writeln('Wiek ',i,': ', baza[i].wiek);
          writeln('Dochody ',i,': ', baza[i].dochody:8:2);
          writeln('---------------------------------');
     end;

end;

procedure zapisz;
begin
     assign(plik,nazwa_bazy);
     rewrite(plik);
     for i:=1 to ileosob do
     begin
          write(plik,baza[i]);
     end;
     close(plik);


end;
begin
     clrscr;
     poczatek;
     wprowadzanie;
     wyswietl;
     wyswietl_wiecej;
     readln;
     zapisz;
     clrscr;
end. 

wszystkie procedury są okej, ale problem jest z procedurą zapis... Zapisuje mi do pliku, ale w tym pliku jest bałagan i w ogóle brzydko :P
To co mam w pliku

testimie test1 ‡ vtestimie2 test2 Ĉ j

testimie to imiona
test 1 i 2 to nazwiska i te teksty w miare dzialają
wiek i dochody to jak sami widzicie, nic tam nie ma tylko jakieś znaczki.
Nie mam pojęcia jak to naprawić. Dodatkowo mam pytanie, czy można zrobić tak, aby te imiona zpaisywały się pod sobą oddzielone "-------------" i w taki sposob:
Imie 1: Ja
Nazwisko 1: My
Wiek 1: 12
Dochody 1: 3233

Imie 2 : 2324
itd..

problem też występuję jak nad close(plik); chcę wpisać write(plik,'traararlala test test: 123'); to wyskakuje błąd ;/
Z góry dziękuję za pomoc ;) Pozdrawiam

0

Em, heloł - zapisujesz cały rekord za pomocą Write, ale już próbujesz odczytać poszczególne pola. Tak się nie da.
Albo zapisujesz cały rekord i odczytujesz cały (write(plik, baza[i]);, read(plik, baza[i]);), albo ręcznie zapisujesz każde pole z osobna i odczytujesz.
Btw, iterowanie tablic od 1 jest złe (do tego sam się machnąłeś w funkcji wyswietl właśnie z liczeniem). Licz jak ludzie, od zera.

0

Procedurę zapis robiłem na wzór kodu mojego nauczyciela u niego jest właśnie w ten sposób. Przy zapisywaniu do pliku w pętli for nie ma baza[i].imie, więc ja nie wiem o co chodzi

0

Wdług mnie powinenem mieć wszystko dobrze nie ? nie bede zapisywał pokolei każdej lini osobno do pliku bo próbowałem i wyskakują błedy.. W tym temacie nie widze odpowiedzi na moj problem? Serio mam problemy z tym i chyba potrzebuje osobnej odpowiedzi dla mnie ;p

0

Chyba rozumiem o co Ci chodzi, w moim poście źle spojrzałem na funkcję wprowadzanie i myślałem, że wczytuje dane z pliku, podczas gdy czyta je od użytkownika - czyli akurat to jest ok.

Zapisuje mi do pliku, ale w tym pliku jest bałagan i w ogóle brzydko

Bo zapisując od razu cały rekord za pomocą write/writeln, zapisywany jest on w taki sposób, w jaki leży w pamięci.
Jeżeli chcesz mieć to ładnie sformatowane, skorzystaj z plików *.ini (moduł IniFiles), plików xml lub zapisuj ręcznie:

procedure zapisz;
begin
     assign(plik,nazwa_bazy);
     rewrite(plik);
     for i:=1 to ileosob do
     begin
          writeln(plik, baza[i].imie);
          writeln(plik, baza[i].nazwisko);
          // (...)
     end;
     close(plik);
end;
0

Zrobilem jak mowisz dalem to tak:

 procedure zapisz;
begin
     assign(plik,nazwa_bazy);
     rewrite(plik);
     for i:=1 to ileosob do
     begin
          writeln(plik,baza[i].imie);
          writeln(plik,baza[i].nazwisko);
          writeln(plik,baza[i].wiek);
          writeln(plik,baza[i].dochody);
     end;
     close(plik);


end;

niestety wyskakuje blad: error63 invlaid file type

i zrobilem z wczesniejszym kodem czyli jak bylo samo write(plik,baza[i]); w petli i zapisalem do .ini i jest to samo, slaczki sa. Sorry za brak polskich znakow ale jestem na wirtualnej maszynie, bo na windowsie 7 nie ma dziala turbo pascal

2

Em, no zgaduję, że musisz mieć jeszcze Var plik: TextFile;? :|
Dodatkowo pozbądź się Turbo Pascala, my tutaj mamy już XXI wiek.

w petli i zapisalem do .ini i jest to samo, slaczki sa

Rozszerzenie jest bez znaczenia. Chodzi o sposób zapisu, a nie rozszerzenie.

0

mam zadeklarowane plik: file of dane; Czy jes tto zły zapis zmiennej plikowej ?... jakie środowisko jak to mówisz na XXI wiek jest dobre ? do pascala?

0

Dzięki, zrobiłem jak pisałeś i dałem plik:text; o dziwo to rozwiązanie działa ;/

1
exevan napisał(a):

mam zadeklarowane plik: file of dane; Czy jes tto zły zapis zmiennej plikowej ?

Robiąc File of typ_rekordowy deklarujesz plik amorficzny, a robiąc TextFile/Text deklarujesz plik tekstowy.
Poczytaj o różnicach.

... jakie środowisko jak to mówisz na XXI wiek jest dobre ? do pascala?

Sam korzystam z Lazarusa, chyba obok płatnego Delphi, najlepsze środowisko do Pascala.

0

Ostatnie pytanie. Czy da radę jakoś sformułować funkcję assign tak aby czytała ze zmiennej nazwę pliku, ale rozszerzenie txt dawało samo.
Mniej więcej tak:

procedure zapisz;
begin
     assign(plik,nazwa_bazy,'.txt');
     rewrite(plik);
     for i:=1 to ileosob do
     begin
          writeln(plik,'Imie ',i,': ',baza[i].imie);
          writeln(plik,'Nazwisko ',i,': ',baza[i].nazwisko);
          writeln(plik,'Wiek ',i,': ',baza[i].wiek);
          writeln(plik,'Dochody ',i,': ',baza[i].dochody:8:2);
          writeln(plik,'-----------------------------');
     end;
     close(plik);
end;  

I jak w pascalu zrobić tabulatory? W c++ jest to znak \t a w pascalu jest coś takiego?

1

Czy da radę jakoś sformułować funkcję assign tak aby czytała ze zmiennej nazwę pliku, ale rozszerzenie txt dawało samo.

Użyj operatora +.

I jak w pascalu zrobić tabulatory? W c++ jest to znak \t a w pascalu jest coś takiego?

O ile się orientuję, to nie ma.
Musisz sprawdzić kod ASCII tego znaku i użyć konstrukcji #kod_ascii.

0

Dzięki :)) Wszystko gra. A jest w pascalu taka funkcja jak sleep(); ? I jak sprawdzić czy dany plik istnieje ?

1

Ad1. Tak trudno sprawdzić?
Ad2. Tak trudno wyszukać info na ten temat?

0

Ze sprawdzaniem istniejącego pliku sprawdzałem i nie udawało mi się tego "wsadzić" w mój kod. Co do funkcji sleep, to na google pokazały mi się same rezultaty związane z funkcją sleep dla c++...

2
exevan napisał(a):

A jest w pascalu taka funkcja jak sleep();?

Jest nawet dokładnie taka, bo jest to funkcja WinAPI (moduł Windows).
Innym odpowiednikiem jest Delay.

I jak sprawdzić czy dany plik istnieje ?

FileExists z modułu SysUtils lub sprawdzać IOResult/wyjątki przy zwykłym Assign+Reset.

0

Ehhh.. Niby większość mam, ale za chiny nie mogę wpaść na pomysł jak przerobić ten kod

program baza_danych;
uses CRT, SysUtils;

type
    dane = record
         imie: string[15];
         nazwisko: string[20];
         wiek: integer;
         dochody: real;
    end;

var
   plik: text;
   baza: array[1..20] of dane;
   nazwa_bazy: string;
   ileosob: integer;
   i, j, ktora: integer;
   opcja: byte;
   znak: char;

procedure menu;
begin
     writeln('----------Witaj w szkolnej bazie danych----------');
     writeln('1 - Wpisywanie danych uczniowskich do bazy danych.');
     writeln('2 - Wyswietlanie poszczegolnych uczniow z bazy danych.');
     writeln('3 - Wyswietlanie wszystkich uczniow z bazy danych od pozycji pierwszej do x.');
     writeln('4 - Zapisywanie danych uczniow do pliku txt.');
     write('Ktora opcje wybierasz: ');
     readln(opcja);
end;

procedure poczatek;
begin
     repeat
     write('Podaj nazwe pliku (bez zadnych rozszerzen): ');
     readln(nazwa_bazy);
     if FileExists(nazwa_bazy+'.txt') then
     begin
          writeln('Baza danych z ta nazwa istnieje. Wprowadz inna.');
          writeln;
     end;
     until not FileExists(nazwa_bazy+'.txt');


end;

procedure wprowadzanie;
begin
     repeat
     write('Podaj ile osob chcesz wprowadzic do bazy (max. 20): ');
     readln(ileosob);
     writeln;
     until (ileosob<=20) and (ileosob>=1);
     for i:=1 to ileosob do
     begin
          write('Podaj ',i,' imie: ');
          readln(baza[i].imie);
          write('Podaj ',i,' nazwisko: ');
          readln(baza[i].nazwisko);
          write('Podaj wiek ',i,' osoby: ');
          readln(baza[i].wiek);
          write('Podaj dochody ',i,' osoby: ');
          readln(baza[i].dochody);
          writeln('----------------------------------');
     end;
 end;
procedure wyswietl;
begin
     j:=0;
     repeat
           write('Podaj ile osob chcesz wyszukac poprzez wpisywanie numerow: ');
           readln(j);
     until (j<=20) and (j>=1);
     for i:=1 to j do
     begin
          repeat
                write('Podaj numer osoby ktora chcesz zobaczyc dane: ');
                readln(ktora);
          until (ileosob<=20) and (ileosob>=1);
          writeln('Imie ',ktora,': ',baza[i].imie);
          writeln('Nazwisko ',ktora,': ',baza[i].nazwisko);
          writeln('Wiek ',ktora,': ',baza[i].wiek);
          writeln('Dochody ',ktora,': ',baza[i].dochody:8:2);
          writeln('--------------------------------------------');
          writeln;
     end;
end;

procedure wyswietl_wiecej;
begin
     clrscr;
     j:=0;
     write('Podaj ile pierwszych osob chcesz dane zobaczyc: ');
     readln(j);
     writeln;
     for i:=1 to j do
     begin
          writeln('Imie ',i,': ',baza[i].imie);
          writeln('Nazwisko ',i,': ',baza[i].nazwisko);
          writeln('Wiek ',i,': ', baza[i].wiek);
          writeln('Dochody ',i,':', baza[i].dochody:8:2);
          writeln('---------------------------------');
     end;
end;

procedure zapisz;
begin
     assign(plik,nazwa_bazy+'.txt');
     rewrite(plik);
     for i:=1 to ileosob do
     begin
          writeln(plik,'Imie ',i,': ',baza[i].imie);
          writeln(plik,'Nazwisko ',i,': ',baza[i].nazwisko);
          writeln(plik,'Wiek ',i,': ',baza[i].wiek);
          writeln(plik,'Dochody ',i,': ',baza[i].dochody:8:2);
          writeln(plik,'-----------------------------');
     end;
     close(plik);
     i:=0;
     write('Trwa zapisywanie do pliku..');
     for i:=1 to 8 do
     begin
          write('.');
          Delay(400);
     end;
     writeln('[ENTER]');
end;

begin
     clrscr;
     poczatek;
     menu;
     case opcja of
          1: wprowadzanie;
          2: wyswietl;
          3: wyswietl_wiecej;
          4: zapisz;
     end;
     readln;
     clrscr;
end.

w taki sposób, aby :

  • po wpisaniu nazwy pliku przechodzi do menu
  • klikam wprowadzanie danych, wprowadzam i żeby po tej czynności powrócić znów do menu. Chciałem spróbować z "label" ale coś mi nie wychodzi.
1
begin
     clrscr;
     poczatek;
     repeat
       menu;
       case opcja of
          1: wprowadzanie;
          2: wyswietl;
          3: wyswietl_wiecej;
          4: zapisz;
       end;
       clrscr;
  Until Opcja = 5;    // w menu dopisz sobie że 5 kończy program
end.
0

Dzięki wielkie wszystkim :)

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