Lazarus readln不读取变量

时间:2018-01-04 16:48:32

标签: pascal lazarus

我想请求一些帮助,因为我无法确定我在下面的代码中做错了什么,就像在程序中一样,它不会读取记录的第一个单元,但之后它会读取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.

1 个答案:

答案 0 :(得分:0)

我注意到FPC Read()ReadLn函数与standard input一起使用时的本质区别并没有很好地记录(在Delphi文档中可以读取它) )。因此,您的问题的答案如下。

根据FPC文档CRLFCRLF,所有文件都被识别为End-Of-Line (EOL)字符,因此在以下{{1}中代表任何一个。

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

下一次调用EOL将立即识别输入缓冲区中的Read(s),并且不会等待用户输入。 EOL继续保留在缓冲区中,因此后续的EOL不会等待用户输入。

Read(s)之后对ReadLn(s)的第一次调用也会立即检测缓冲区中的Read(s),而不是等待用户输入。

调用EOL 时,程序会等待(如上例所示)用户输入,直到将ReadLn(s)添加到输入缓冲区。直到(但不包括)EOL的输入字符将从缓冲区中删除并传递到EOL然后将s从缓冲区中删除并丢弃

下一次调用EOL将再次停止并等待用户输入。

在您的代码中,您在执行的最开始时调用ReadLn(s)。然后,在Read(n)中,您正在调用beiras(),它会检测缓冲区中的ReadLn(),因此会立即返回,但也会从缓冲区中删除EOL。对EOL的后续调用现在将等待用户输入。

治愈是如何在计划开始时将ReadLn()更改为Read()n