Pascal Lazarus readln没有';t读取变量

Pascal Lazarus readln没有';t读取变量,pascal,lazarus,Pascal,Lazarus,我想寻求一些帮助,因为我无法识别以下代码中的错误,因为在过程中,它不会读取记录的第一个单元,但之后它也会读取uj.nev。它只是第一次错过它,这是我无法理解的,不仅在学校的电脑上,而且在我的电脑上。如果你能向我解释我做错了什么,我将不胜感激。提前谢谢!(程序应该读取记录nev、varos、fizetes,并将它们按升序排序,然后将其写入文本文件) 程序adatbazis; 使用crt、Sysutils; 常数 C_FNAME='adatbazis.txt'; 变量 a、 n,j,l:整数; tf

我想寻求一些帮助,因为我无法识别以下代码中的错误,因为在过程中,它不会读取记录的第一个单元,但之后它也会读取uj.nev。它只是第一次错过它,这是我无法理解的,不仅在学校的电脑上,而且在我的电脑上。如果你能向我解释我做错了什么,我将不胜感激。提前谢谢!(程序应该读取记录nev、varos、fizetes,并将它们按升序排序,然后将其写入文本文件)

程序adatbazis;
使用crt、Sysutils;
常数
C_FNAME='adatbazis.txt';
变量
a、 n,j,l:整数;
tfout:文本文件;
类型
Tember=记录
内华达州:字符串;
瓦罗斯:弦;
菲泽特人:长;
结束;
程序beiras(var uj:Tember);
开始
书面语('nev',j',:');
readln(美国内华达州);
书面语('varos',j',:');
readln(uj.varos);
书面语('fizetes',j',:');
readln(uj.fizetes);
结束;
变量
i、 k:整数;
seged:Tember;
坟墓:泰伯的阵列[1..20];
开始
写('n:');
读取(n);
对于j:=1到n,开始
贝拉斯(坟墓[j]);
结束;
书面语(“Mi szerint legyen会合?”);
重复
书面语('Nev:1,Fizetes:2,varos:3');
readln(l);
直到L1或2或3;
如果l=1,则开始
对于j:=1到n-1,开始
对于k:=2到n,开始
如果坟墓[j].nev>坟墓[k].nev那么
开始
分段:=坟墓[j];
坟墓[j]:=坟墓[k];
坟墓[k]:=分段;
结束;
结束;
结束;
结束;
如果l=2,则开始
对于j:=1到n-1,开始
对于k:=2到n,开始
如果坟墓[j].fizetes>坟墓[k].fizetes那么
开始
分段:=坟墓[j];
坟墓[j]:=坟墓[k];
坟墓[k]:=分段;
结束;
结束;
结束;
结束;
如果l=3,则开始
对于j:=1到n-1,开始
对于k:=2到n,开始
如果坟墓[j].varos>坟墓[k].varos那么
开始
分段:=坟墓[j];
坟墓[j]:=坟墓[k];
坟墓[k]:=分段;
结束;
结束;
结束;
结束;
AssignFile(tfout,C_FNAME);
重写(tfout);
对于i:=1到n,开始
writeln(tfout,坟墓[i].nev',坟墓[i].varos',坟墓[i].fizetes);
结束;
关闭文件(tfout);
clrsc;
书面形式(“完成”);
readln;
结束。

我注意到,当与标准输入一起使用时,
FPC
Read()
ReadLn
函数之间的本质区别没有很好的文档记录(在Delphi文档中可以阅读)。因此,你的问题的答案如下

根据
FPC
文档,
CRLF
CR
LF
,所有字符都被识别为
行尾(EOL)
字符,因此在下面的
EOL
中代表任何字符

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

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

ReadLn(s)
读取后的第一次调用
ReadLn(s)
也将立即检测缓冲区中的
EOL
,而不是等待用户输入

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

下次调用
ReadLn
将再次停止并等待用户输入

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


解决方法是在程序开始时将
Read()n
更改为
ReadLn(n)

我对这个问题的回答中的工作示例:可能会帮助您看到哪里出了问题。简单地说,如果您试图在文件中存储包含
字符串
字段的记录,您需要非常小心,并了解您正在做什么。除了格式不好,使其难以读取之外,您还存在一些问题。例如,你认为,
重复。。。直到L1或2或3真的吗?为什么在调试程序之前问这个问题?这还不够好。我告诉过你要仔细阅读以了解差异,然后验证你是否正确使用了它们,不是吗?不合理的尝试直到不再失败才算是编程。请停止这种徒劳的编程尝试。调试你的程序。
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.