Zapisywanie do pliku

0

Witam. Dzisiaj mam problem z exitcode 101.
W moim programie miał pobierać 13 danych od użytkownika. I zapisać do pliku tekstowego, jak zapisze miał odczytać z pliku tekstowego i wypisać na ekranie.
Program wywala błąd przy procedurze, która teoretycznie miała wczytywać dane z pliku tekstowego. Działam na Free Pascal IDE.

read(f,tablica[i]);

A oto program.

program nazwa;
uses crt;
Type
Dane=record
Imie:string[20];
Nazwisko:string[40];
Data_urodzenia:string[60];
Data_imienin:string[60];
end;
var f:file of Dane;
tablica:array[1..13] of dane;

procedure zapisywanie;
var i:integer;
begin
Clrscr;
writeln('Zapisywanie danych:' );
for i:=1 to 13 do
with tablica[i] do
begin
writeln('Podaj dane o ',i,' uczniu: ');
writeln('Podaj imie: ');
readln(imie);
writeln('Podaj nazwisko : ');
readln(nazwisko);
writeln('Podaj date urodzenia: ');
readln(Data_urodzenia);
writeln('Podaj date imienin: ');
readln(Data_imienin);
end;
end;

procedure zapisywanie_do_pliku;
var i:integer;
begin
assign(f,'Dane.txt');
rewrite(f);
for i:=1 to 13 do write(f,tablica[i]);
writeln('Utworzylem plik z danymi, o nazwie Dane.txt');
writeln('Aby kontynuowac wcisnij ENTER');
readln;
close(f);
end;

procedure wypisz;
var i:integer;
begin
writeln('Podaj numer osoby, ktora chcesz zobaczyc dane: ');
readln(i);
// WARUNEK
assign(f,'dane.txt');
reset(f);
read(f,tablica[i]);
with tablica[i] do
begin
writeln('Imie: ');
readln(imie);
writeln('Nazwisko : ');
readln(nazwisko);
writeln('Data urodzenia: ');
readln(Data_urodzenia);
writeln('Data imienin: ');
readln(Data_imienin);
close(f);
end;
end;

begin
zapisywanie;
zapisywanie_do_pliku;
wypisz;
end.
0

Po pierwsze formatuj kod. Jeżeli nie umiesz tego robić samodzielnie, posiłkuj się http://olesio.eu/delfor . Po drugie nazywaj instrukcje i zmienne z wielkich liter, są wtedy czytelniejsze. A kod powinien wyglądać tak jak poniżej. Sprawdziłem dla jednej osoby na szybko, ale dla 13 czy więcej też powinien zadzialać. Tylko w swojej procedurze sprawdzania danych wybranej osoby zastosuj Val (opis na: Val) żeby upenić się, że ktoś podał na pewno prawidłową liczbę całkowitą będącą w zakresie tablicy.

program nazwa;

uses
  crt;

const
  N = 13;

type
  Dane = record
    Imie : string[20];
    Nazwisko : string[40];
    Data_urodzenia : string[60];
    Data_imienin : string[60];
  end;

var
  F : File of Dane;
  Tablica : array[1..N] of dane;

procedure zapisywanie;
var
  I : integer;
begin
  Clrscr;
  Writeln('Zapisywanie danych:');
  for i := Low(Tablica) to High(Tablica) do
    with Tablica[I] do
    begin
      Writeln('Podaj dane o ', i, ' uczniu: ');
      Write('Podaj imie: ');
      Readln(imie);
      Write('Podaj nazwisko : ');
      Readln(nazwisko);
      Write('Podaj date urodzenia: ');
      Readln(Data_urodzenia);
      Write('Podaj date imienin: ');
      Readln(Data_imienin);
    end;
end;

procedure zapisywanie_do_pliku;
var
  I : integer;
begin
  Assign(F, 'Dane.txt');
  Rewrite(f);
  for i := Low(Tablica) to High(Tablica) do
    Write(f, Tablica[I]);
  Writeln('Utworzylem plik z danymi, o nazwie Dane.txt');
  Writeln('Aby kontynuowac wcisnij ENTER');
  Close(F);
  Readln;
end;

procedure wypisz;
var
  I : integer;
begin
  Write('Podaj numer osoby, ktora chcesz zobaczyc dane: ');
  Readln(I);
  assign(F, 'dane.txt');
  reset(F);
  Read(f, Tablica[I]);
  with Tablica[I] do
  begin
    Writeln('Imie: ', imie);
    Writeln('Nazwisko :', nazwisko);
    Writeln('Data urodzenia: ', Data_urodzenia);
    Writeln('Data imienin: ', Data_imienin);
  end;
  Close(F);
  Readln;
end;

begin
  zapisywanie;
  zapisywanie_do_pliku;
  wypisz;
end.
0

Nie wiem co się stało ale działa, dzięki za pomoc. Myślałem nad warunkiem co kontroli poprawności czy jest w zakresie tablicy.

0

Jednak działa tylko tak jak nie chciałem. Jak wpisuje w program 5 wypisuje nie wiem dlaczego wypisuje osobę nr.1.

0

To oczywiste. Przecież za każdym razem gdy wywołujesz procedurę otwiera ona plik, pozycja w pliku jest na jego początku, wczytywany jest pierwszy rekord (niezależnie od tego ile wynosi I) i umieszczany w Tablica[I].
Musisz wczytać wszystkie rekordy a dopiero potem na żądanie wyświetlać informacje o wybranej osobie.

0

Dla mnie nie jasne : ] Dla kogoś kto nie umie programować nie jest zawsze jasne, co dla osoby, która umie programować. : ]

0

Dlaczego mi wypisuje pierwszą osobę ?
Chociaż zastosowałem fora ?

program nazwa;

uses
  crt;

const
  N = 13;

type
  Dane = record
    Imie : string[20];
    Nazwisko : string[40];
    Data_urodzenia : string[60];
    Data_imienin : string[60];
  end;

var
  F : file of Dane;
  C : file of Dane;
  Tablica : array[1..N] of dane;
  o : integer; znak : char;

procedure zapisywanie;
var
  I : integer;
begin
  Clrscr;
  Writeln('Zapisywanie danych:');
  for i := 1 to 13 do
    with Tablica[I] do
    begin
      Writeln('Podaj dane o ', i, ' uczniu: ');
      Write('Podaj imie: ');
      Readln(imie);
      Write('Podaj nazwisko: ');
      Readln(nazwisko);
      Write('Podaj date urodzenia: ');
      Readln(Data_urodzenia);
      Write('Podaj date imienin: ');
      Readln(Data_imienin);
    end;
end;

procedure zapisywanie_do_pliku;
var
  I : integer;
begin
  Assign(F, 'Dane.txt');
  Rewrite(f);
  for i := 1 to 13 do
    Write(f, Tablica[I]);
  Writeln('Utworzylem plik z danymi, o nazwie Dane.txt');
  Writeln('Aby kontynuowac wcisnij ENTER');
  Close(F);
  Readln;
end;

procedure wypisz;
var
  I, d : integer;
begin // BEGIN PROCEDURY
  Write('Podaj numer osoby, ktora chcesz zobaczyc dane: ');
  Readln(d);
  if (d >= 1) and (d <= 13) then
  begin // BEGIN WARUNKU
    for i := 1 to 13 do
    begin // BEGIN FORA
      assign(F, 'dane.txt');
      reset(F);
      Read(f, Tablica[I]);
      if d = i then
      begin // BEGIN WARUNKU
        with Tablica[I] do
        begin // BEGIN WITHA
          Writeln('Imie: ', imie);
          Writeln('Nazwisko :', nazwisko);
          Writeln('Data urodzenia: ', Data_urodzenia);
          Writeln('Data imienin: ', Data_imienin);
        end; // END WITHA
        Close(F);
        assign(c, 'Dane_o_uczniu.txt');
        rewrite(c);
        write(c, Tablica[i]);
        close(c);
        writeln('Utworzylem plik z danymi o uczniu o nazwie "Dane_o_uczniu.txt".');
      end // END WARUNKU
      else close(f);
    end; // END FORA
  end //END WARUNKU
  else Writeln('Bledna liczba.');
  writeln('Aby kontynuowac wcisnij ENTER');
  Readln;
end;

begin
  repeat
    writeln('Wybierz opcje: ');
    writeln('1 - Wpisanie danych do programu.');
    writeln('2 - Wyszukanie danych jednego ucznia oraz zapisanie jego danych.');
    readln(o);
    case o of
      1 :
        begin
          zapisywanie;
          zapisywanie_do_pliku;
        end;
      2 : wypisz;
    else writeln('Bledna liczba');
    end;
    readln;
    clrscr;
    writeln('Czy chcesz zakonczyc program ? (T/N).');
    readln(znak);
  until UpCase(znak) = 'T';
  writeln('Koniec programu.');
  Delay(3000);
end.
0

To nie działa, bo z każdym krokiem pętli otwierasz plik i odczytujesz pierwszy rekord i znów go zamykasz. Daj otwieranie pliku przed pętle i zamykanie za pętle i chyba powinno działać.

0

luke18dg, wbrew temu, co Ci się wydaje, pliki tworzone w programie to nie pliki tekstowe, ale pliki zdefiniowane. Dla plików zdefiniowanych jest dostępna procedura Seek, która ustawia położenie pliku bezpośrednio przed elementem podanym jako drugi parametr. Dzięki temu, gdy chcemy odczytać z pliku dane np. 10 osoby, to nie musimy w pętli odczytywać poprzednich 9.

Procedura odczytu z pliku będzie więc taka (prostsza):

procedure wypisz;
var
  I, d : integer;
  Osoba: Dane;
begin
  Write('Podaj numer osoby, ktorej dane chcesz zobaczyc: ');
  Readln(d);
  if (d >= 1) and (d <= 13) then begin
    Assign(F, 'dane.txt');
    Reset(F);
    Seek(F, d-1);    // d-1, bo elementy są numerowane od zera
    Read(F, Osoba);
    Close(F);
    with Osoba do begin
      Writeln('Imie: ', imie);
      Writeln('Nazwisko :', nazwisko);
      Writeln('Data urodzenia: ', Data_urodzenia);
      Writeln('Data imienin: ', Data_imienin);
    end;
    Assign(C, 'Dane_o_uczniu.txt');
    Rewrite(C);
    Write(C, Osoba);
    Close(C);
    Writeln('Utworzylem plik z danymi o uczniu o nazwie "Dane_o_uczniu.txt".');
  end
  else Writeln('Bledna liczba.');
  writeln('Aby kontynuowac wcisnij ENTER');
  Readln;
end;

Nie kompilowałem tego kodu, więc będziesz musiał poprawić ewentualne błędy.

0

Dzięki wielkie :D Dosyć dużo skróci mój to program : ]

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