26. príklady


Posledná zmena: 19.2.2003

Banner Text binárne súbory

binárny súbor čísel

typový binárny súbor reálnych čísel:

Daný je binárny súbor cisla.dat, ktorý obsahuje postupnosť reálnych čísel. Dopíšte na jeho koniec priemer týchto čísel. Riešte pomocou typového súboru.

var
  fr:file of real;
  x,sum:real;
  poc:integer;
begin
  AssignFile(fr,'cisla.dat'); Reset(fr);
  sum:=0; poc:=0;
  while not eof(fr) do begin
    read(fr,x); sum:=sum+x; inc(poc);
  end;
  sum:=sum/poc;
  write(fr,sum);
  CloseFile(fr);
end;

netypový binárny súbor reálnych čísel:

predchádzajúca úloha pomocou netypového binárneho súboru

var
  f:file;
  x,sum:real;
  poc:integer;
begin
  AssignFile(f,'cisla.dat');
  Reset(f,sizeof(real));
  sum:=0; poc:=0;
  while not eof(f) do begin
    blockread(f,x,1); sum:=sum+x;
    inc(poc);
  end;
  sum:=sum/poc;
  blockwrite(f,sum,1);
  CloseFile(f);
end;

binárny súbor reálnych čísel ako údajový prúd STREAM:

predchádzajúca úloha pomocou údajového prúdu

var
  f:TStream;
  x,sum:real;
  poc:integer;
begin
  f:=TFileStream.Create('cisla.dat',fmOpenReadWrite);
  sum:=0; poc:=0;
  while f.Position < f.Size do begin
    f.Read(x,sizeof(real)); sum:=sum+x;
    inc(poc);
  end;
  sum:=sum/poc;
  f.Write(sum,sizeof(real));
  f.Free;
end;

binárny súbor bodov:

Vytvorte binárny súbor obrazok.dat, do ktorého budete "zapisovať obrázok" nakreslený myšou na obrazovku. Kreslí sa pri stlačenom ľavom tlačidle myši, teda pri stlačení tlačidla otvoríme súbor na zapisovanie a potom, až kým sa tlačidlo nepustí, zapisujeme pri pohybe myši do súboru jej súradnice - typ TPoint.

var
  fmys:file of TPoint;

procedure TForm1.Image1MouseDown(...);
var
  xy:TPoint;
begin
  if ssLeft in Shift then begin
    AssignFile(fmys,'obrazok.dat'); Rewrite(fmys);
    xy:=Point(x,y); write(fmys,xy); 
  end;
end;

procedure TForm1.Image1MouseMove(...);
var
  xy:TPoint;
begin
  if ssLeft in Shift then begin
    xy.x:=x; xy.Y:=y; write(fmys,xy);
  end;
end;

procedure TForm1.Image1MouseUp(...);
begin
  CloseFile(fmys);
end;

nakreslenie obrázka podľa bodov v súbore:

Nakreslite obrázok, ktorý je popísaný v súbore obrazok.dat z predchádzajúceho príkladu.

var
  fmys:file of TPoint;
  xy:TPoint;
  prvy:boolean;
begin
  AssignFile(fmys,'obrazok.dat'); Reset(fmys);
  prvy:=true;
  while not eof(fmys) do begin
    read(fmys,xy);
    if prvy then begin
      g.MoveTo(xy.x,xy.y); prvy:=false;
    end
    else
      g.LineTo(xy.x,xy.y);
  end;
end;

Ďalšie úlohy

  • do binárneho súboru ukladajte nielen body obrázka (TPoint) - podobne ako predchádzajúci príklad - ale aj informácie o tom, že je kresba prerušená a pero sa presunie na iné miesto

minsort:

Daný je binárny súbor cisla.dat obsahujúci celé čísla. Usporiadajte čísla v súbore vzostupne algoritmom MinSort (resp. InsertSort). Nepoužívajte žiadne štruktúrované premenné ani pomocný súbor. So súborom pracujte ako s netypovým.

var
  f:file;
  i,j,min,imin,pom:integer;
begin
  AssignFile(f,'cisla.dat'); Reset(f,sizeof(integer));
  for i:=0 to filesize(f)-2 do begin
    seek(f,i); blockread(f,min,1); imin:=i;
    while not eof(f) do begin
      blockread(f,j,1);
      if j<min then begin
        min:=j; imin:=filepos(f)-1;
      end;
    end;
    if imin<>i then begin
      seek(f,i); blockread(f,pom,1);
      seek(f,i); blockwrite(f,min,1);
      seek(f,imin); blockwrite(f,pom,1);
    end;
  end;
  CloseFile(f);
end;

string v binárnom súbore

  • typ string[číslo] na rozdiel od string nie je smerník ale staticky vyhradená pamäť veľkosti o 1 viac ako číslo v [ ]
  • ak do súboru zapisujeme recordy, ktoré majú obsahovať reťazce, nesmieme použiť veľké stringy ale len string[číslo];
  • ak potrebujeme do binárneho súboru zapisovať veľké reťazce, najprv zapíšeme dĺžku (napr. ako 4-bajtové celé číslo) a za tým príslušnú postupnosť znakov
    • treba si dávať pozor na zápis prázdneho reťazca, lebo vtedy neexistuje s[1]

zápis reťazcov do binárneho súboru:

Daný je textový súbor texty.txt. Presypte jeho obsah do binárneho súboru texty.dat  po riadkoch. Teda každý riadok z texty.txt budete chápať ako string  a do texty.dat ho zapíšete tak, že najprv zapíšete jeho dĺžku a potom príslušný string.

var
  t:TextFile;
  f:file;
  s:string;
  d:integer;
begin
  AssignFile(t,'texty.txt'); Reset(t);
  AssignFile(f,'texty.dat'); Rewrite(f,1);
  while not eof(t) do begin
    readln(t,s); d:=length(s);
    blockwrite(f,d,sizeof(integer)); 
    if d>0 then

      blockwrite(f,s[1],d);
  end;
  CloseFile(t);
  CloseFile(f);
end;

čítanie reťazcov z binárneho súboru:

Napíšte funkciu, ktorá zistí, či sú posledné dva najdlhšie reťazce z binárneho súboru texty.dat (z predchádzajúceho príkladu) rovnaké, alebo nie.

function rovnake:boolean;
var
  f:file;
  d:integer;
  s,s1,s2:string;
begin
  AssignFile(f,'texty.dat'); Reset(f,1);
  s1:=''; s2:='';
  while not eof(f) do begin
    blockread(f,d,sizeof(integer));
    SetLength(s,d);
    if d>0 then

      blockread(f,s[1],d);
    if d>=length(s1) then begin s2:=s1; s1:=s; end
    else if d>=length(s2) then s2:=s;
  end;
  Result:=s1=s2;
  CloseFile(f);
end;

prečítanie textového súboru do jedného reťazca:

Napíšte program, ktorý do reťazca prečíta naraz celý textový súbor aj so značkami koncov riadkov. Použite netypový súbor. Takýto reťazec môžeme celý priradiť do textovej plochy Memo.

var
  f:file;
  s:string;
  d:integer;
begin
  AssignFile(f,'subor.txt'); Reset(f,1);
  d:=filesize(f);
  SetLength(s,d);
  if d>0 then
    blockread(f,s[1],d);
  CloseFile(f);
  Memo1.Lines.Text:=s;
end;

predchádzajúci príklad pomocou údajového prúdu:

 

var
  f:TStream;
  s:string;
begin
  f:=TFileStream.Create('subor.txt',fmOpenRead);
  SetLength(s,f.Size);
  if f.Size>0 then
    f.read(s[1],f.Size);
  f.Free;
  Memo1.Lines.Text:=s;
end;

Ďalšie úlohy

  • vytvorte textový súbor - postupnosť reťazcov - len pomocou netypového súboru, resp. pomocou údajového prúdu

súbor záznamov

úloha:

Daný je binárny súbor studenti.dat, ktorý obsahuje informácie o študentoch študujúcich na odbore informatika v prvom ročníku. Položka spolužiak obsahuje číslo vety v súbore, v ktorej je meno ďalšieho spolužiaka z rovnakého krúžku (posledný z krúžku v zozname odkazuje na prvého z rovnakého krúžku).

Napíšte program, ktorý vytvorí binárny súbor kruzok.dat. Tento súbor by mal obsahovať všetkých študentov, ktorí patria do rovnakého krúžku ako prvý študent v súbore studenti.dat.

// Veta v súbore je typu
type
  veta=record
    meno:string[10];
    kruzok:byte;
    znamka:real;
    spoluziak:integer;
  end;

pomocou typového súboru:

 

var
  f,ff:file of veta;
  v:veta;
begin
  AssignFile(ff,'studenti.dat'); Reset(ff);
  AssignFile(f,'kruzok.dat'); Rewrite(f);
  if not Eof(ff) then begin
    Read(ff,v);
    Write(f,v);
    while v.spoluziak <> 0 do begin
      seek(ff,v.spoluziak);
      Read(ff,v);
      Write(f,v);
    end;
  end;
  CloseFile(ff);
  CloseFile(f);
end;

pomocou netypového súboru s dĺžkou vety sizeof(veta):

 

var
  f,ff:file;
  v:veta;
begin
  AssignFile(ff,'studenti.dat'); Reset(ff,sizeof(v));
  AssignFile(f,'kruzok.dat'); Rewrite(f,sizeof(v));
  if not Eof(ff) then begin
    BlockRead(ff,v,1);
    BlockWrite(f,v,1);
    while v.spoluziak <> 0 do begin
      seek(ff,v.spoluziak);
      BlockRead(ff,v,1);
      BlockWrite(f,v,1);
    end;
  end;
  CloseFile(ff);
  CloseFile(f);
end;

pomocou údajového prúdu Stream:

 

var
  f,ff:TStream;
  v:veta;
begin 
  ff:=TFileStream.Create('studenti.dat',fmOpenRead);
  f:=TFileStream.Create('kruzok.dat',fmCreate);
  if ff.Position<>ff.Size then begin
    ff.Read(v,sizeof(v));
    f.Write(v,sizeof(v));
    while v.spoluziak <> 0 do begin
      ff.seek(v.spoluziak*sizeof(v),soFromBeginning);
      ff.Read(v,sizeof(v));
      f.Write(v,sizeof(v));
    end;
  end;
  ff.Free;
  f.Free;
end;

Ďalšie úlohy

  • Dané sú deklarácie:
    • type
        Student = record
          meno,priezv:string;
          rocnik:byte;
          kruzok:string;
          adresa:string;
        end;
        PStudent = ^Student;
        PoleStud = array of PStudent;
      
        StVeta = record
          meno,priezv:string[20];
          rocnik:byte;
          kruzok:string[4];
          stpriem:real;
        end;

    Napíšte procedúru aktual s parametrom P:PoleStud, ktorá bude aktualizovať P podľa údajov v binárnom súbore nevyhoveli.dat (pevná dĺžka viet) tak, že uvoľní miesta v pamäti, ktoré zaberajú záznamy o študentoch uvedených v tomto súbore. Vety v súbore sú typu StVeta. Úlohu riešte typovým súborom aj pomocou TStream.

  • Napíšte program, ktorý interpretuje binárny súbor kor.dat, v ktorom sa nachádzajú príkazy korytnačej grafiky. V každej vete súboru je jeden príkaz. Vety v súbore sú rôznej dĺžky a sú v ňom tesne za sebou. Každá veta začína 1-bajtovým kódom príkazu:
      type prikaz=(oDopredu,oVlavo,oVpravo,oZmenFP,oPH,oPD);
    Za príkazmi oDopredu,oVlavo,oVpravo nasleduje v súbore ich parameter - reálne číslo, za príkazom oZmenFP nasleduje jeho parameter - celé číslo (TColor) a príkazy oPH a oPD nemajú parametre. Úlohu riešte typovým súborom aj pomocou TStream.
  • Daný je binárny súbor slovnik.dat, v ktorom sú slová uložené takto: 1. bajt určuje dĺžku slova, za ním nasleduje prvé slovo (príslušný počet bajtov), za tým nasledujú ďalšie slová. Slová sú usporiadané lexikograficky. Napíšte booleovskú funkciu Bin_je(s:string):boolean; ktorá zistí, či sa dané slovo s nachádza v slovníku. Použite binárne vyhľadávanie. Zadefinujte pomocné funkcie: pocetSlov a iteSlovo(i:integer). So súborom pracujte pomocou TStream.
  • Daná je deklarácia vety súboru:
    • type  
        veta = record  
          meno:string[50];  
          priemer:real;  
          internat:boolean;  
        end;

    Daný je súbor studenti.dat, ktorého vety sú typu veta. Vytvorte (indexové) súbory uspesni.dat a internat.dat (súbory celých čísel), ktoré obsahujú čísla viet (od 0) súboru studenti.dat, ktorí sú úspešní (priemer do 1.5), resp. ktorí majú internát. Na základe indexového súboru index.dat vytvorte zo súboru studenti.dat súbor vyber.dat, len tých viet, ktorých číslo je v súbore indexov. So súbormi pracujte len pomocou TStream


© 2003 AB, KVI
blaho@fmph.uniba.sk