Przejrzenie kodu zapis z txt do pliku binarnego

0

Napisać procedurę

function raport(plik_we : string; plik_bin : string):boolean
generującą na podstawie takiego pliku tekstowego (nazwa pliku przekazana w nagłówku procedury - plik_txt) plik binarny (nazwa pliku przekazana w nagłówku procedury - plik_bin) zawierający rekordy następującej postaci:

type
Osoba = record
   imie, nazwisko : string[20];
  st_konta : real;
end;
var
  plikb:file of Osoba;

W pliku wejściowym nazwiska mogą się powtarzać i należy to traktować jako stan kolejnego konta tej samej osoby. W takim przypadku należy dokonać sumowania stanów kont. Do realizacji programu należy użyć tablicę statyczną o rozmiarze N = 100000. Jeżeli w czasie wykonywania funkcji tablica robocza zostanie przekroczona, funkcja zwraca wartość false, w przeciwnym razie zwraca wartość true.

plik tekstowy:
Jan
Nowak
1000
Marek
Kowal
5100
Jan
Nowak
2050
plik binarny:
Jan
Nowak
3050
Marek
Kowal
5100

Główny program

program Bank;

uses
  mraport;

var
  sciezka_do_txt:string;
  sciezka_do_bin:string;

begin
    Write('sciezke do txt: ');
    ReadLn(sciezka_do_txt);
    Write('sciezke do bin: ');
    ReadLn(sciezka_do_bin);
    raport(sciezka_do_txt, sciezka_do_bin);
end.

Własny moduł

unit mraport;

interface

uses
  sysUtils;

const
  N = 100000;

TYPE
    osoba = RECORD
      imie:string[20];
      nazwisko:string[20];
      st_konta:real;
      istnieje:boolean;
    END;

tab_pom = array[0..N] of osoba;

var
  plik_txt:text;
  plik_bin:file of tab_pom;
  tab:tab_pom;
  licznik:integer;

function wczytajtxt(sciezka_plik_txt:string; var t:tab_pom):boolean;
procedure suma(var t:tab_pom);
procedure zapiszbin(sciezka_plik_bin:string; const t:tab_pom);
function raport(sciezka_plik_txt:string; sciezka_plik_bin:string):boolean;

implementation

function wczytajtxt(sciezka_plik_txt:string; var t:tab_pom):boolean;
var
	str:string;
	i, j:integer;
	r:real;
begin
  assign(plik_txt, sciezka_plik_txt);
  reset(plik_txt);
  i := 0;
  j := 0;
  repeat
  begin
    inc(i);
    if i = 1 then
    begin
      readln(plik_txt, str);
      t[j].imie:=str;
    end;
    if i = 2 then
    begin
      readln(plik_txt, str);
      t[j].nazwisko:=str;
    end;
    if i = 3 then
    begin
      readln(plik_txt, str);
      r := strtofloat(str);
      t[j].ST_KONTA := r;
      t[j].istnieje := true;
      i := 0;
      inc(j);
    end;
    if j > n then break;
  end;
  until eof(plik_txt);
  close(PLIK_TXT);

  if j>  n then
    wczytajtxt := false
  else
  begin
    licznik := j;
    wczytajtxt := true;
  end;

end;

procedure suma(var t:tab_pom);
var
  i,j:integer;
begin
  for i := 0 to licznik-1 do
  for j := i+1 to licznik do
  begin
    if (t[i].nazwisko = t[j].nazwisko) and (t[i].imie = t[j].imie) then
    begin
      t[i].st_konta := t[i].st_konta + t[J].st_konta;
      t[j].nazwisko := '';
      t[j].imie := '';
      t[j].st_konta := 0;
      t[J].istnieje := false;
    end;
  end;
end;

procedure zapiszbin(sciezka_plik_bin:string; const t:tab_pom);
var
  i:integer;
begin
  assign(plik_bin, sciezka_plik_Bin);
  rewrite(plik_bin);
  for i := 0 to licznik do
  begin
    if t[i].istnieje = true then
      write(plik_bin, t);
  end;
  close(plik_bin);
end;

function raport(sciezka_plik_txt:string; sciezka_plik_bin:string):boolean;
begin
  wczytajtxt(sciezka_plik_txt,tab);
  if wczytajtxt(sciezka_plik_txt,tab) = false then 
    raport:=false
  else
  begin
    suma(tab);
    zapiszbin(sciezka_plik_bin, tab);
    raport := true;
  end;
  end;
end.

end.

Program kompiluje się poprawnie tworzy plik binarny o wielkości aż 18 mb! :) Czy wielkość pliku jest przyczyną tablicy roboczej czy mam coś źle zapisane? Wydaje mi sie że wszystko jest ok.

0

Zapisujesz całą tablice na 100001 osob po 46 bajtów na każdą czyli 4600046 tyle razy ile miałeś osób w pliku czyli skoro mówisz że 18 mb to znaczy że zapisałeś 4 - osoby.

Nie wiem po kiego robisz "zbędne ruchy", np:

function wczytajtxt(sciezka_plik_txt:string; var t:tab_pom):boolean;
var os:osoba;
var i,k:Integer;
var more:Boolean;
begin
  Assign(plik_txt,sciezka_plik_txt);
  Reset(plik_txt);
  for i:=0 to N do
  begin
    more:=true;
    while more do
    begin
      more:=false;
      ReadLn(plik_txt,os.imie);
      ReadLn(plik_txt,os.nazwisko);
      ReadLn(plik_txt,os.ST_KONTA);
      for k:=0 to i-1 do
      begin
        if (tb[k].imie=os.imie)and(tb[k].nazwisko=os.nazwisko) then
        begin
          tb[k].ST_KONTA:=tb[k].ST_KONTA+os.ST_KONTA;
          more:=true;
          break;
        end;
      end;
    end;
    tb[i]:=os;
    licznik:=i+1;
  end;
  wczytajtxt :=(licznik>N);
  if not wczytajtxt then licznik:=0;
end;

dwie funkcji w jednej a na dodatek znacznie krótsze niż każda z tych dwóch, no i odpada potrzeba istnienia dziwnego pola w strukturze.

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