Lazarus readln 不读取变量
Lazarus readln doesn't read the variable
我想寻求一些帮助,因为我无法确定我在以下代码中做错了什么,就像在过程中一样,它没有读取记录的第一个单元,但之后它也读取 uj.nev。它只是第一次错过它,这是我无法理解的,不仅在学校的计算机上,而且在我的计算机上也是如此。如果您能向我解释我做错了什么,我将不胜感激。提前致谢! (程序应该读取记录 nev 、 varos 、 fizetes ,并将它们按升序排序,然后将其写入文本文件)
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.
我注意到 FPC
Read()
和 ReadLn
函数与 standard input
一起使用时的本质区别没有很好的记录(在 Delphi 可以阅读的文档)。因此,您的问题的答案如下。
根据FPC
文档,CRLF
、CR
和LF
都被识别为End-Of-Line (EOL)
字符,所以在下面的EOL
代表其中任何一个。
当调用 Read(s)
时,其中 s: string;
程序等待用户输入,直到将 EOL
添加到输入缓冲区。 EOL
之前的输入字符(但不包括)从缓冲区中删除并传递给 s
。 EOL
留在输入缓冲区。
下一次调用 Read(s)
将立即识别输入缓冲区中的 EOL
,并且不会等待用户输入。 EOL
继续保留在缓冲区中,因此后续 Read(s)
将不会等待用户输入。
在 Read(s)
之后第一次调用 ReadLn(s)
也会立即检测缓冲区中的 EOL
而不是等待用户输入。
当调用 ReadLn(s)
时,程序会等待(如前例所示)用户输入,直到将 EOL
添加到输入缓冲区。 EOL
之前的输入字符(但不包括)从缓冲区中删除并传递给 s
。 然后EOL
从缓冲区中移除并丢弃。
下一次调用 ReadLn(s)
将再次停止并等待用户输入。
在您的代码中,您在执行的最开始调用 Read(n)
。然后,在 beiras()
中调用 ReadLn()
,它会检测缓冲区中的 EOL
,因此会立即检测到 returns,但也会从缓冲区中删除 EOL
。对 ReadLn()
的后续调用现在将等待用户输入。
治疗方法 是将程序开头的 Read()n
更改为 ReadLn(n)
。
我想寻求一些帮助,因为我无法确定我在以下代码中做错了什么,就像在过程中一样,它没有读取记录的第一个单元,但之后它也读取 uj.nev。它只是第一次错过它,这是我无法理解的,不仅在学校的计算机上,而且在我的计算机上也是如此。如果您能向我解释我做错了什么,我将不胜感激。提前致谢! (程序应该读取记录 nev 、 varos 、 fizetes ,并将它们按升序排序,然后将其写入文本文件)
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.
我注意到 FPC
Read()
和 ReadLn
函数与 standard input
一起使用时的本质区别没有很好的记录(在 Delphi 可以阅读的文档)。因此,您的问题的答案如下。
根据FPC
文档,CRLF
、CR
和LF
都被识别为End-Of-Line (EOL)
字符,所以在下面的EOL
代表其中任何一个。
当调用 Read(s)
时,其中 s: string;
程序等待用户输入,直到将 EOL
添加到输入缓冲区。 EOL
之前的输入字符(但不包括)从缓冲区中删除并传递给 s
。 EOL
留在输入缓冲区。
下一次调用 Read(s)
将立即识别输入缓冲区中的 EOL
,并且不会等待用户输入。 EOL
继续保留在缓冲区中,因此后续 Read(s)
将不会等待用户输入。
在 Read(s)
之后第一次调用 ReadLn(s)
也会立即检测缓冲区中的 EOL
而不是等待用户输入。
当调用 ReadLn(s)
时,程序会等待(如前例所示)用户输入,直到将 EOL
添加到输入缓冲区。 EOL
之前的输入字符(但不包括)从缓冲区中删除并传递给 s
。 然后EOL
从缓冲区中移除并丢弃。
下一次调用 ReadLn(s)
将再次停止并等待用户输入。
在您的代码中,您在执行的最开始调用 Read(n)
。然后,在 beiras()
中调用 ReadLn()
,它会检测缓冲区中的 EOL
,因此会立即检测到 returns,但也会从缓冲区中删除 EOL
。对 ReadLn()
的后续调用现在将等待用户输入。
治疗方法 是将程序开头的 Read()n
更改为 ReadLn(n)
。