I would like to ask for some help as i'm not able to identify what i did wrong in the following code as in the procedure , it doesn't read the first unit of the record , but after that it reads the uj.nev too. It only misses it for the first time which is what i can't understand ,and not only on the school computer but mine too. I would appreciate it if you could explain to me what i did wrong. Thanks in advance! (the program supposed to read records nev , varos , fizetes , and sort them into ascending order, and then write it out into a text file)
program adatbazis;
uses crt,Sysutils;
const
C_FNAME = 'adatbazis.txt';
var
a,n,j,l:integer;
tfout: Textfile;
type
Tember=record
nev:string;
varos:string;
fizetes:longint;
end;
procedure beiras(var uj:Tember);
begin
writeln('nev',j,':');
readln(uj.nev);
writeln('varos',j,':');
readln(uj.varos);
writeln('fizetes',j,':');
readln(uj.fizetes);
end;
var
i,k:integer;
seged:Tember;
tomb: array[1..20] of Tember;
begin
write('n :');
read(n);
for j:= 1 to n do begin
beiras(tomb[j]);
end;
writeln('Mi szerint legyen rendezve?');
repeat
writeln(' Nev:1 , Fizetes:2 , varos:3');
readln(l);
until l<> 1 or 2 or 3;
if l=1 then begin
For j:= 1 to n-1 do begin
for k:= 2 to n do begin
if tomb[j].nev>tomb[k].nev then
begin
seged:=tomb[j];
tomb[j]:=tomb[k];
tomb[k]:=seged;
end;
end;
end;
end;
if l=2 then begin
For j:= 1 to n-1 do begin
for k:= 2 to n do begin
if tomb[j].fizetes>tomb[k].fizetes then
begin
seged:=tomb[j];
tomb[j]:=tomb[k];
tomb[k]:=seged;
end;
end;
end;
end;
if l=3 then begin
For j:= 1 to n-1 do begin
for k:= 2 to n do begin
if tomb[j].varos>tomb[k].varos then
begin
seged:=tomb[j];
tomb[j]:=tomb[k];
tomb[k]:=seged;
end;
end;
end;
end;
AssignFile(tfout, C_FNAME);
rewrite(tfout);
for i:=1 to n do begin
writeln(tfout,tomb[i].nev,' ',tomb[i].varos,' ',tomb[i].fizetes);
end;
CloseFile(tfout);
clrscr;
writeln('done');
readln;
end.
I noticed that the essential difference between the FPC
Read()
and ReadLn
functions when used with standard input
is not very well documented (in the Delphi documentation it can be read). Therefore, the answer to your question is the following.
According to the FPC
documentation, CRLF
, CR
and LF
, all are recognized as End-Of-Line (EOL)
characters, so in the following EOL
stands for any of those.
When calling Read(s)
where s: string;
the program waits for user input until an EOL
is added to the input buffer. The input characters up until (but excluding) the EOL
are removed from the buffer and passed to s
. The EOL
is left in the input buffer.
Next call to Read(s)
will immediately recognize the EOL
in the input buffer, and will not wait for user input. The EOL
continues to remain in the buffer, and therefore no subsequent Read(s)
will wait for user input.
The first call to ReadLn(s)
after a Read(s)
will also immediately detect the EOL
in the buffer and not wait for user input.
When calling ReadLn(s)
the program waits (as in previous example) for user input until an EOL
is added to the input buffer. The input characters up until (but excluding) the EOL
are removed from the buffer and passed to s
. Then the EOL
is removed from the buffer and thrown away.
Next call to ReadLn(s)
will again stop and wait for user input.
In your code you are calling Read(n)
in the very beginning of the execution. Then, in beiras()
you are calling ReadLn()
which detects the EOL
in the buffer and therefore returns immediately, but also removes the EOL
from the buffer. Subsequent calls to ReadLn()
will now wait for user input.
The cure is iow to change the Read()n
to a ReadLn(n)
in the beginning of your program.