25.Prednaska/Cvicenie0: Rozdiel medzi revíziami

Z Pascal
Prejsť na: navigácia, hľadanie
Riadok 23: Riadok 23:
  
 
1. zadeklarovať údajový prúd ako objekt '''TFileStream''' (pozor, je to trieda), vytvoriť inštanciu (vytvoriť nový súbor) a hneď zatvoriť
 
1. zadeklarovať údajový prúd ako objekt '''TFileStream''' (pozor, je to trieda), vytvoriť inštanciu (vytvoriť nový súbor) a hneď zatvoriť
* meno inštancie môžete zvoliť ľubovoľné, napr. Subor, Stream, FileStream, F, Dada, Prud, ...
+
* meno inštancie môžete zvoliť ľubovoľné, napr. Subor, Data, Stream, FileStream, F, Dada, Prud, ...
 
  var
 
  var
 
   F: TFileStream;
 
   F: TFileStream;
Riadok 150: Riadok 150:
 
     F.WriteBuffer(R, SizeOf(Real));
 
     F.WriteBuffer(R, SizeOf(Real));
 
   end;
 
   end;
 
+
 
 
   F.Position := 0;
 
   F.Position := 0;
 
   while F.Position < F.Size do
 
   while F.Position < F.Size do
Riadok 177: Riadok 177:
 
     F.WriteBuffer(R, SizeOf(Real));
 
     F.WriteBuffer(R, SizeOf(Real));
 
   end;
 
   end;
 
+
&nbsp;
 
   F.Position := 0;
 
   F.Position := 0;
 
   while F.Position < F.Size do
 
   while F.Position < F.Size do
Riadok 191: Riadok 191:
  
  
 +
10. vieme vypísať všetkých 256 dvojíc čísel, teraz chceme iba jednu dvojicu, poradové číslo zadané zo vstupu (priamy prístup)
 +
var
 +
  F: TFileStream;
 +
  I, Index: Integer;
 +
  R: Real;
 +
begin
 +
  F := TFileStream.Create('file.dat', fmOpenReadWrite);
 +
  repeat
 +
    Write('? ');
 +
    ReadLn(Index);
 +
    {{Blue|F.Position :{{=}} Index * (SizeOf(Integer) + SizeOf(Real));}}
 +
    F.ReadBuffer(I, SizeOf(Integer));
 +
    F.ReadBuffer(R, SizeOf(Real));
 +
    WriteLn(I, ' ', R:0:2, ' ');
 +
  until Index = 0;
 +
  F.Free;
 +
* prípadne vyskúšať bez násobenia v priradení do '''Position'''
 +
 +
 +
11. do súboru dáme 256 rôznych znakov (#0..#255)
 +
var
 +
  F: TFileStream;
 +
  C: Char;
 +
begin
 +
  F := TFileStream.Create('file.dat', {{Blue|fmOpenReadWrite}});
 +
  for C := #0 to #255 do
 +
    F.WriteBuffer(C, SizeOf(Char));
 +
  F.Free;
 +
* keď pozrieme v hex-editore, prvých 256 bajtov je rovnakých, ako keď sme zaposovali '''Byte''' 0..255
 +
* ďalej nasleduje skoro 3 kilo bajty smetí, ktoré tam ostali z predchádzajúceho príkladu
 +
* niekoľko možností:
 +
:* do '''Create''' dať '''fmCreate'''
 +
:* pred for-cyklu dať
 +
      F.Size := 0;
 +
:* za for-cyklus dať
 +
      F.Size := F.Position;
 +
 +
 +
12. ďalej sa bude pracovať so statickým poľom celých čísel
 +
* zaplniť pole druhými mocninami
 +
* naraz celé zapísať
 +
* po jednom vypisovať
 +
var
 +
  F: TFileStream;
 +
  Pole: array [1..100] of Integer;
 +
  I: Integer;
 +
begin
 +
  for I := 1 to High(Pole) do
 +
    Pole[I] := I * I;
 +
  F := TFileStream.Create('file.dat', fmOpenReadWrite);
 +
  F.WriteBuffer(Pole, SizeOf(Pole));
 +
&nbsp;
 +
  {{Red// F.Position :{{=}} 0;}}
 +
  while F.Position < F.Size do
 +
  begin
 +
    F.ReadBuffer(I, SizeOf(Integer));
 +
    Write(I, ' ');
 +
  end;
 +
  F.Free;
 +
* najprv vyskúšať bez '''Position := 0;'''
 +
* while-cyklus jednopduchšie pomocou funkcie '''ReadDWord'''
 +
  while F.Position < F.Size do
 +
    Write(F.{{Blue|ReadDWord}}, ' ');
  
  

Verzia zo dňa a času 13:00, 15. február 2013

25. Cvičenie


< 25.Prednáška | riešené úlohy


Rozcvička

1. kopírovať textový súbor cisla.txt do cisla1.txt

  • kde vstupný súbor obsahuje v každom riadku jedno celé číslo a výstupný súbor bude obsahovať všetky čísla zo vstupu okrem posledného
  • nepoužívajte polia ani reťazce


2. textový súbor cisla.txt obsahuje len celé čísla, pričom v niektorých riadkoch ich môže byť aj niekoľko, alebo niektoré riadky môžu byť aj prázdne

  • prečítať súbor a vypísať poradové číslo riadku, v ktorom je najväčší súčet čísel a vypísať aj tento súčet
  • nepoužívajte polia ani reťazce


3. prečítajte textový súbor subor.txt a vypíšte počet prázdnych riadkov v tomto súbore

  • nepoužívajte reťazce


Cvičenie

1. zadeklarovať údajový prúd ako objekt TFileStream (pozor, je to trieda), vytvoriť inštanciu (vytvoriť nový súbor) a hneď zatvoriť

  • meno inštancie môžete zvoliť ľubovoľné, napr. Subor, Data, Stream, FileStream, F, Dada, Prud, ...
var
  F: TFileStream;
begin
  F := TFileStream.Create('file.dat', fmCreate);
  F.Free;
  WriteLn('done');
  ReadLn;
end.
  • vznikne prázdny súbor - dá sa skontrolovať v prieskumníkovi


2. metódy WriteBuffer a ReadBuffer zapisujú a čítajú zo súboru - prvý parameter musí byť premenná

  • do súboru zapísať 256 bajtov od 0 do 255
var
  F: TFileStream;
  B: Byte;
begin
  F := TFileStream.Create('file.dat', fmOpenReadWrite); // môže tu byť namiesto fmCreate, lebo súbor už existuje
  for B := 0 to 255 do
    F.WriteBuffer(B, SizeOf(Byte));
  F.Free;
  • v prieskumníkovi vidíme, že súbor má presne 256 bajtov
  • môžeme skontrolovať obsah v PSPad - v hexeditore, resp. na tabuľu naznačiť prvých niekoľko bajtov súboru


3. to isté, ale zapisujeme Word - po 2 bajty

var
  F: TFileStream;
  W: Word;
begin
  F := TFileStream.Create('file.dat', fmOpenReadWrite);
  for W := 0 to 255 do
    F.WriteBuffer(W, SizeOf(Word));
  F.Free;
  • v prieskumníkovi vidíme, že súbor má presne 512 bajtov
  • môžeme skontrolovať obsah v PSPad - v hexeditore


4. to isté, ale zapisujeme Integer - po 4 bajty

var
  F: TFileStream;
  I: Integer;
begin
  F := TFileStream.Create('file.dat', fmOpenReadWrite);
  for I := 0 to 255 do
    F.WriteBuffer(I, SizeOf(Integer));
  F.Free;
  • v prieskumníkovi vidíme, že súbor má presne 1024 bajtov
  • môžeme skontrolovať obsah v PSPad - v hexeditore


5. vypísať tento súbor - v cykle čítať celé čísla

var
  F: TFileStream;
  I, N: Integer;
begin
  F := TFileStream.Create('file.dat', fmOpenReadWrite);
  for I := 0 to 255 do
  begin
    F.ReadBuffer(N, SizeOf(Integer));   // tu sa nesmie čítať do I
    Write(N, ' ');
  end;
  F.Free;


6. čo sa stane, keď pred for-cyklus príde priradenie do Position a cyklus len do 254:

var
  F: TFileStream;
  I, N: Integer;
begin
  F := TFileStream.Create('file.dat', fmOpenReadWrite);
  F.Position := 4;
  for I := 0 to 254 do
  begin
    F.ReadBuffer(N, SizeOf(Integer));
    Write(N, ' ');
  end;
  F.Free;
  • môže sa vyskúšať nemeniť hornú hranicu cyklu - program spadne
  • začne sa vypisovať až od 4. bajtu, teda prvé celé číslo sa prekočí:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 ...


7. to isté, ale Position := 1

  • vypíše sa 255 divných čísel:
16777216 33554432 50331648 67108864 83886080 100663296 117440512 134217728 15099
4944 167772160 184549376 201326592 218103808 234881024 251658240 268435456 28521
2672 301989888 318767104 335544320 352321536 369098752 385875968 402653184 41943 ...
  • uvažovať o tom, čo sa stalo - pomôže pozrieť v hex-editore
  • môžeme výpis nie desiatkovo ale 16-ovo (treba SysUtils do uses):
var
  F: TFileStream;
  I, N: Integer;
begin
  F := TFileStream.Create('file.dat', fmOpenReadWrite);
  F.Position := 1;
  for I := 0 to 254 do
  begin
    F.ReadBuffer(IntToHex(N, 8), SizeOf(Integer));
    Write(N, ' ');
  end;
  F.Free;
  • teraz výpis
01000000 02000000 03000000 04000000 05000000 06000000 07000000 08000000 09000000
 0A000000 0B000000 0C000000 0D000000 0E000000 0F000000 10000000 11000000 1200000
0 13000000 14000000 15000000 16000000 17000000 18000000 19000000 1A000000 1B0000 ...
  • prípadne porovnať s takýmto 16-ovým výpisom aj pre Position := 4, keď to bolo ešte dobre:
00000001 00000002 00000003 00000004 00000005 00000006 00000007 00000008 00000009
 0000000A 0000000B 0000000C 0000000D 0000000E 0000000F 00000010 00000011 0000001
2 00000013 00000014 00000015 00000016 00000017 00000018 00000019 0000001A 000000 ...


8. zapísať a potom aj vypísať 256 reálnych čísel - pozrieť v hex-editore - zistiť veľkosť súboru

  • dve vlastnosti Position a Size môžeme použiť na otestovanie konca súboru (nemáme EOF)
  • namiesto for-cyklu pri čítaní while (kým nie je koniec súboru)
var
  F: TFileStream;
  I: Integer;
  R: Real;
begin
  F := TFileStream.Create('file.dat', fmOpenReadWrite);
  for I := 0 to 255 do
  begin
    R := I;
    F.WriteBuffer(R, SizeOf(Real));
  end;
 
  F.Position := 0;
  while F.Position < F.Size do
  begin
    F.ReadBuffer(R, SizeOf(Real));
    Write(R:0:2, ' ');
  end;
  F.Free;
  • výpis
0.00 1.00 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00 10.00 11.00 12.00 13.00 14.00
15.00 16.00 17.00 18.00 19.00 20.00 21.00 22.00 23.00 24.00 25.00 26.00 27.00 28 ...
  • vyskúšať čítať tento súbor a vypisovať ako Integer (prípadne Byte alebo Word)


9. do súboru zapisovať dvojice: celé číslo od 0..255 a realne číslo s tou istou hodnotou:

var
  F: TFileStream;
  I: Integer;
  R: Real;
begin
  F := TFileStream.Create('file.dat', fmOpenReadWrite);
  for I := 0 to 255 do
  begin
    F.WriteBuffer(I, SizeOf(Integer));
    R := I;
    F.WriteBuffer(R, SizeOf(Real));
  end;
 
  F.Position := 0;
  while F.Position < F.Size do
  begin
    F.ReadBuffer(I, SizeOf(Integer));
    F.ReadBuffer(R, SizeOf(Real));
    Write(I, ' ', R:0:2, ' ');
  end;
  F.Free;
  • tento súbor obsahuje 512 čísel pričom sa striedajú Integer a Real
  • pozrieť aj v hex-editore
  • uvedomiť si, že keby nám neprezradili, čo a ako je v ňom uložené, ťažšie sa to zistí, ťažšie sa zistí, či to čo čítame (napr. najprv Real a potom Integer) je zlý výsledok


10. vieme vypísať všetkých 256 dvojíc čísel, teraz chceme iba jednu dvojicu, poradové číslo zadané zo vstupu (priamy prístup)

var
  F: TFileStream;
  I, Index: Integer;
  R: Real;
begin
  F := TFileStream.Create('file.dat', fmOpenReadWrite);
  repeat
    Write('? ');
    ReadLn(Index);
    F.Position := Index * (SizeOf(Integer) + SizeOf(Real));
    F.ReadBuffer(I, SizeOf(Integer));
    F.ReadBuffer(R, SizeOf(Real));
    WriteLn(I, ' ', R:0:2, ' ');
  until Index = 0;
  F.Free;
  • prípadne vyskúšať bez násobenia v priradení do Position


11. do súboru dáme 256 rôznych znakov (#0..#255)

var
  F: TFileStream;
  C: Char;
begin
  F := TFileStream.Create('file.dat', fmOpenReadWrite);
  for C := #0 to #255 do
    F.WriteBuffer(C, SizeOf(Char));
  F.Free;
  • keď pozrieme v hex-editore, prvých 256 bajtov je rovnakých, ako keď sme zaposovali Byte 0..255
  • ďalej nasleduje skoro 3 kilo bajty smetí, ktoré tam ostali z predchádzajúceho príkladu
  • niekoľko možností:
  • do Create dať fmCreate
  • pred for-cyklu dať
      F.Size := 0;
  • za for-cyklus dať
      F.Size := F.Position;


12. ďalej sa bude pracovať so statickým poľom celých čísel

  • zaplniť pole druhými mocninami
  • naraz celé zapísať
  • po jednom vypisovať
var
  F: TFileStream;
  Pole: array [1..100] of Integer;
  I: Integer;
begin
  for I := 1 to High(Pole) do
    Pole[I] := I * I;
  F := TFileStream.Create('file.dat', fmOpenReadWrite);
  F.WriteBuffer(Pole, SizeOf(Pole));
 
  Šablóna:Red// F.Position := 0;
  while F.Position < F.Size do
  begin
    F.ReadBuffer(I, SizeOf(Integer));
    Write(I, ' ');
  end;
  F.Free;
  • najprv vyskúšať bez Position := 0;
  • while-cyklus jednopduchšie pomocou funkcie ReadDWord
  while F.Position < F.Size do
    Write(F.ReadDWord, ' ');


Domáca úloha

1. napíšte program, ktorý vytvorí binárny súbor