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文档,CRLFCRLF都被识别为End-Of-Line (EOL)字符,所以在下面的EOL 代表其中任何一个。

当调用 Read(s) 时,其中 s: string; 程序等待用户输入,直到将 EOL 添加到输入缓冲区。 EOL 之前的输入字符(但不包括)从缓冲区中删除并传递给 sEOL留在输入缓冲区

下一次调用 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)