Mi a hiba a programkódban? (Pascal)
Ez csak egy egyszerű program. Amikor be akarom olvasni a fájlt egyszerűen meghibásodik. De szerintem nem azzal van a gond, mert amikor teljesen üres (0kb), akkor nem hal meg, szóval a fájl írásnál lehet a gond, de nem értem, mert nincs hiba a programkódban.
program hidas;
uses crt;
type
hidtip=record
nev:string;
tipus:string;
folyo:string;
ev:integer;
hosz:word;
end;
var
hidak:array[1..100] of hidtip;
hid:hidtip;
fajl:file of hidtip;
i,db:integer;
be:char;
begin
clrscr;
{$I-}
assign(fajl,'hid.dat');
reset(fajl);
{$I+}
if ioresult<>0 then
begin
writeln('A fajl nem talalhato. A letrehozashoz nyomjon meg egy billentyut.');
readkey;
rewrite(fajl);
write('A fajl letrehozva');
readkey;
clrscr;
end
else
begin
db:=1;
while not(eof(fajl)) do
begin
read(fajl,hidak[db]);
inc(db);
end;
i:=1;
repeat
with hidak[i] do
begin
writeln(nev);
writeln(tipus);
writeln(folyo);
writeln(ev);
writeln(hosz);
writeln(i,'. record');
end;
be:=readkey;
case be of
#77:if i<db then inc(i);
#75:if i>1 then dec(i);
end;
clrscr;
until be=#27;
end;
db:=0;
write('Nev: ');
readln(hid.nev);
while hid.nev<>'' do
begin
with hid do
begin
write('Tipus: ');
readln(tipus);
write('Folyo: ');
readln(folyo);
write('Ev: ');
readln(ev);
write('Hossz: ');
readln(hosz);
end;
inc(db);
hidak[db]:=hid;
write('Nev: ');
readln(hid.nev);
end;
close(fajl);
rewrite(fajl);
for i:=1 to db do write(fajl,hidak[db]);
end.
1) A végén nem zárod le a fájlt. (még ez a legkisebb gond)
2) A Turbo Pascal még nem tudott record típust olvasni, írni, és rekord típusú fájlt kezelni. Nem tudom, ezt azóta megcsinálták-e, de szerintem nem.
Pontosan mi a hiba, amit kiír?
lezártam a fájlt, így se jó.
olvasásnál meghal és előjön az Assembler.
Nekem működik.(Free pascallal próbáltam)
Nekem az volt vele a gondom hogy a kódból kellett kibogarásznom hogy hogy kell használni a programot.
Turbo pascallal blockread/blockwrite eljárásokkal lehet (nem szöveges) file-t írni olvasni.
köszi a segítséget.
én lazarus-al írtam, free-vel működik. ezentúl dos-os programokat nem írok lazarusban.
A rekord típusnál ha a rekordban stringet használsz illik annak megadni a hosszát, valahogy így:
hidtip=record
nev:string[50];
tipus:string[50];
folyo:string[50];
ev:integer;
hosz:word;
end;
FreePascal és Lazarus esetében ugyanis előfordulhat, hogy nem a Turbo Pascalban általános string típust jelenti a string, hanem ansistringet, aminek a hossza bármekkora lehet, nincsen limitálva 255 karakterben. Amikor pedig egy ilyet olvasol vissza egy fájlból a programod nem tudja, hogy mekkora is pontosan egy rekord mérete és ezért lehetnek gondok. Hiszen a rekordnak többek között az a lényege, hogy a rekord típusodnak megfelelő méretű blokkokat olvasol/írsz a fájlba, amelyek mérete minden körülmények között azonos.
zsomkovacs, butaságokat ne beszéljél, a Turbo Pascal kiválóan kezeli a rekordokat, a rekord típusú fájlokkal egyetemben.
A "for i:=1 to db do write(fajl,hidak[db]);" nem jó, mindig az utolsó megadott rektodott rekordot fogja a file-ba írni db-szer.
for i:=1 to db do write(fajl,hidak[i]); lenne a helyes.
"A rekord típusnál ha a rekordban stringet használsz illik annak megadni a hosszát, valahogy így: "...
Igen, vagyis ha nem adod meg a hosszát akkor nem garantált hogy jól fog működni a file-ba írás/olvasás.
"én lazarus-al írtam, free-vel működik. ezentúl dos-os programokat nem írok lazarusban."
Már bocsánat de ez nem jó hozzáállás, free pascal-on sem garantált hogy minden esetben működik, más beállításokkal vagy ha vannak a kódba bizonyos fordítási direktívák. Különben a lazarus is free pascal comiler-t használ.
Egyébként nem dos-os program mert dos-on nem futna, hanem windos-os konzolos alkalmazás (console application).
"FreePascal és Lazarus esetében ugyanis előfordulhat, hogy nem a Turbo Pascalban általános string típust jelenti a string, hanem ansistringet, aminek a hossza bármekkora lehet, nincsen limitálva 255 karakterben. Amikor pedig egy ilyet olvasol vissza egy fájlból a programod nem tudja, hogy mekkora is pontosan egy rekord mérete és ezért lehetnek gondok."
Igaz hogy nincs limitálva a hossza, de az indoklás nem igaz. Nem azért nem működik mert nem tudja a rekord méretét, a rekord mérete minden esetben fix.
A string[50] belső ábrázolása 51 byte a 0. byte tárolja a string hosszát az utána lévő byte-ok a string karaktereit.
A string belső ábrázolása fordítási direktíváktól/fordítási beállításoktól függ. Free pascal esetén alapértelmezett beállítás szerint ugyan az mintha string[255]-öt írtam volna. 255-nél nem lehet hosszabb mert a 0. byte tárolja a hosszt és egy byte-on 255-nél nagyobb érték nem ábrázolható. A hosszabb string érték ábrázolásának érdekében más ábrázolási módot használ. A rekord a string értéke helyett egy pointert tárol ami rámutat arra a memóriaterület kezdőcímére ahol a string karaterei vannak.(Egy dinamikusan foglalt memóriaterület.) File-ba íráskor ezeket a pointereket írja ki, későbbi visszaolvasáskor ezeket a pointereket olvassa vissza ami akkor már érvénytelen memóriaterületre mutatnak.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!