Miképp lehet fájlbeolvasással kiegészíteni egy programot Free Pascalban?
Adott egy kész program, ami billentyűzetes bevitellel készült, és tökéletesen fut. Most feladatul kaptuk azt, hogy ezt bővítsük ki választható opciókkal, úgyhogy a billentyűzet mellett fájlból olvasva is le kell tudnia futnia. Addig még megvagyok, hogy a fájlbeolvasást lefuttatom, de ott már elakadtam, hogy a meglévő eljárásokba ezt hogy integrálom bele? Mert jelen állapotában ha a billentyűzetes beolvasást választom, akkor fut, ha a fájlból olvasást, runtime errort kapok. Miképp ágyazzam bele az eljárásokba is a fájlműveletet, hogy működjön? (A TXT-ben egy darabszám szerepel, és annak megfelelő mennyiségű további szám)
A kód:
program beadando;
const MaxN=10000;
type
meres=Array [1..MaxN] of integer;
var
N:integer;
mm,st,veg,szakk,szakv: meres;
f: text;
//Beolvas
Procedure beolvas(var N:integer);
Var
i,ssz: integer;
Begin
Writeln('Adj meg egy szamot: 0 (billentyuzetrol bevitel) vagy 1 (fajlbol olvasas)?');
Read(ssz);
if (ssz = 0) then
Begin
readln(N);
for i:=1 to N do begin
readln(mm[i]);
end;
end;
if (ssz = 1) then
Begin
Assign(f,'adat.txt');
reset(f);
Readln(f,N);
for i:=1 to N do
begin
Readln(f,mm[i]);
end;
close(f);
reset(f);
End;
if ((ssz <> 0) and (ssz <> 1)) then
Begin
Writeln('Hibas szam! Add meg ujra!');
End;
end;
//1. feladat
Procedure arviz(const N: integer; const mm: meres);
var i,K: integer;
Begin
i:=0;
K:=0;
while (i<=N) do
begin
i:=i+1;
if (mm[i]>800) then
begin
K:=K+1;
while (mm[i]>800) do
begin
i:=i+1;
end;
end;
end;
writeln(K);
end;
//2-3-4. feladat
Procedure szakasz(const N: integer; const mm: meres; var st,veg,szakk,szakv: meres);
var i,j,z,l,sv: integer;
Begin
j:=0;
i:=0;
while (i<=N) do
begin
i:=i+1;
if (mm[i] > 800) then
begin
j:=j+1;
st[j]:=i;
while (mm[i] > 800) do
begin
i:=i+1;
end;
veg[j]:=i-1;
end;
end;
i:=0;
sv:=0;
while (i<=j) do
begin
i:=i+1;
z:=st[i];
l:=0;
while (z<veg[i]) do
begin
if (((mm[z]>1000) and (mm[z+1]<=1000)) or ((mm[z]>900) and (mm[z+1]<=900))) then
begin
l:=1;
end;
z:=z+1;
end;
if (l=1) then
begin
sv:=sv+1;
szakk[sv]:=st[i];
szakv[sv]:=veg[i];
end;
end;
for i:=1 to j do
begin
write(st[i],' ');
write(veg[i],' ');
end;
writeln();
writeln(sv);
for i:=1 to sv do
begin
write(szakk[i],' ');
write(szakv[i],' ');
end;
writeln();
end;
Begin
beolvas(N);
arviz(N,mm);
szakasz(N,mm,st,veg,szakk,szakv);
End.
Biztos van elég adat a fájlban? Nem többet próbálsz beolvasni belőle? A Close(f) után miért van egy Reset(F)?
Próbáld ki így:
program beadando;
{$mode objfpc}{$H+}
uses crt,SysUtils;
const MaxN=10000;
type
meres=Array [1..MaxN] of integer;
var
N:integer;
mm,st,veg,szakk,szakv: meres;
//Beolvas
procedure billentyuzetrol(var N:integer);
var
i: integer;
begin
writeln('Hány darab mérési eredményt kíván beírni?');
readln(N);
for i:=1 to N do
readln(mm[i]);
end;
procedure fajlbol(aFileName:string);
var
i: integer;
f: text;
begin
if FileExists(aFileName) then
begin
assign(f,aFileName);
reset(f);
readln(f,N);
for i:=1 to N do
readln(f,mm[i]);
end;
end;
Procedure beolvas();
Var
ch: char;
Begin
repeat
clrscr;
Writeln('Adj meg egy szamot: 0 (billentyuzetrol bevitel) vagy 1 (fajlbol olvasas)?');
ch:=ReadKey;
if not (ch in ['0'..'1']) then
begin
writeln('Hibás válasz! A folytatáshoz nyomjon Entert!');
readln();
end;
until ch in ['0'..'1'];
case ch of
'0' : billentyuzetrol(N);
'1' : fajlbol('adat.txt');
end;
end;
//1. feladat
Procedure arviz(const N: integer; const mm: meres);
var i,K: integer;
Begin
i:=0;
K:=0;
while (i<=N) do
begin
i:=i+1;
if (mm[i]>800) then
begin
K:=K+1;
while (mm[i]>800) do
begin
i:=i+1;
end;
end;
end;
writeln(K);
end;
//2-3-4. feladat
Procedure szakasz(const N: integer; const mm: meres; var st,veg,szakk,szakv: meres);
var i,j,z,l,sv: integer;
Begin
j:=0;
i:=0;
while (i<=N) do
begin
i:=i+1;
if (mm[i] > 800) then
begin
j:=j+1;
st[j]:=i;
while (mm[i] > 800) do
begin
i:=i+1;
end;
veg[j]:=i-1;
end;
end;
i:=0;
sv:=0;
while (i<=j) do
begin
i:=i+1;
z:=st[i];
l:=0;
while (z<veg[i]) do
begin
if (((mm[z]>1000) and (mm[z+1]<=1000)) or ((mm[z]>900) and (mm[z+1]<=900))) then
begin
l:=1;
end;
z:=z+1;
end;
if (l=1) then
begin
sv:=sv+1;
szakk[sv]:=st[i];
szakv[sv]:=veg[i];
end;
end;
for i:=1 to j do
begin
write(st[i],' ');
write(veg[i],' ');
end;
writeln();
writeln(sv);
for i:=1 to sv do
begin
write(szakk[i],' ');
write(szakv[i],' ');
end;
writeln();
end;
Begin
beolvas();
arviz(N,mm);
szakasz(N,mm,st,veg,szakk,szakv);
End.
Hopp. A fájlt én is elfelejtettem lezárni :). A fajlbol eljárás alábbi része így helyes:
for i:=1 to N do
readln(f,mm[i]);
close(f);
A fájlban ugye nincsenek tizedestörtek?
Ez vér ciki lesz, de közben kiderült, hogy az én verzióm is tökéletesen fut: ott rontottam el, hogy ugye adat.txt-t kell keressen és futtasson a program. Nos, én sikeresen el is neveztem adat.txt-nek a fájlt, amit így automatikusan adat.txt.txt-ként érzékelt... nem az én napom. :D
Még egyszer köszönöm szépen a segítségedet! :)
Nincs mit :).
Annyi megjegyzésem azért lenne, hogy ha programozol, jobb ha megszokod, hogy beszédes változóneveket illene használni, illetve célszerű gondolni rá, hogy a kész programot esetleg más is fogja használni nem csak te, ezért az adatbevitelt és kiírást úgy kellene megcsinálni, hogy az beszédes legyen, hogy a felhasználó tudja, h mi miért történik. Adatbevitelnél pedig mindig célszerű figyelni a hibakezelésre, mert mi történik ha a programod egy egész típusú számot vár, de a felhasználó egy tizedestörtet ír be neki, vagy mondjuk betűket stb.
Ezeket azért javítsd ki: i := i + 1 → Inc(i) stb...
writeln();
writeln(sv); →
writeln(#10#13, sv);
write(szakk[i],' ');
write(szakv[i],' '); →
write(szakk[i], ' ', szakv[i], ' '); és adj egy kis pofát is neki. Ha már nem tartod az ősrégi Pascal ajánlást miszerint a foglalt szavak kisbetűsek stb... akkor legalább legyen egységes.
Rendben, köszönöm szépen a tanácsokat! :)
Viszont időközben beleütköztem még egy problémába: tud a Pascal úgy fájlból dolgozni, hogy nem előre megadott nevű fájlt keres? Gondolok itt arra, hogy nincs előre megadva az, hogy az adat.txt-t keresse, hanem a felhasználó maga adja meg. Mert kipróbáltam, hogy kibővítem a (lentebb bemásolt) sorokat, de runtime errort kapok futtatásnál:
if (ssz = 1) then
begin
writeln('Add meg a fajl nevet: ');
readln(fajlnev);
Assign(f,fajlnev);
reset(f);
Readln(f,N);
for i:=1 to N do
begin
Readln(f,mm[i]);
end;
close(f);
Mielőtt megnyitnád a fájlt ellenőrizd, hogy létezik e. (FileExists(fajlnev) <-- kell hozzá a sysutils unit.
Ha a fájlnév nem tartalmaz elérési utat, akkor a fájlt a program mappájában fogja keresni a program.
Windows alatt az ékezetes és egyéb speciális karaktereket tartalmazó fájlnevek és elérési utak bezavarnak. Ezeket nem kezeli rendesen a Free Pascal.
Prímán lefut a Te általad írt program, nagyon szépen köszönöm, viszont azt nem értem, hogy az enyémnél felvettem a sysUtils-t, és kibővítettem a kódot:
if (ssz = 1) then
begin
writeln('Add meg a fajl nevet: ');
read(fajlnev);
if FileExists(fajlnev) then
begin
... kód többi része
end;
Viszont ahogy megnyomom az egyest, rögtön kilép a program. Ezt mi okozhatja? Bocsi, hogy ennyi minden - talán alap - dolgot kérdezek, csak szeretném megérteni a dolgok mikéntjét. :)
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!