【问题标题】:Variable or constant expression required , Pascal需要变量或常量表达式,Pascal
【发布时间】:2016-07-13 07:02:20
【问题描述】:

constant vs variable

嗨,我目前正在处理文件。其全局声明的 Char 文件。我试图在 char 文件中查找任何字母(A、b 等),我知道每行只有一个字符,我想将其更改为点。 (变量 TECKA - DOT) 当我想写 char 时,它会显示“预期的常量表达式”,但是当我将其更改为常量(注释部分中的代码)时,它会显示“需要变量”。我在这里做错了什么? 谢谢回复。

procedure TForm1.Button3Click(Sender: TObject);
var znak,tecka:char;
begin
  tecka:='.';
  assignfile(f,'Znaky.dat');
  reset(f);
  While not eof(f) do begin
    read(f,znak);
    Case znak of 'a'..'z','A'..'Z':
      seek(f,filepos(f)-1);
      Write(f,tecka);           // write(f,'.');
    end;
  end;
  closefile(f);
end;

【问题讨论】:

  • 请不要将代码放在图像中,只需将代码作为文本粘贴到问题中即可。

标签: file delphi variables constants pascal


【解决方案1】:

您做错了什么与write(f,tecka); 行无关,而是与pascal 中的块规则有关。

如果你想让编译器停止抱怨,你需要将 case 语句更改为:

case znak of 
  'a'..'z','A'..'Z': begin
    seek(f,filepos(f)-1);
    write(f,tecka);
  end;
end; {case}

问题在于 case 语句在 of 之后需要一个或多个常量表达式(例如 'a'..'z')。在: 之后,您只能放置一个语句或一个开始结束块。因为您在 : 之后放置了 2 个语句,所以 Pascal 想要将第二个语句解释为另一个 case 子句(例如:'0'..'9':),但事实并非如此。

如果您想在一个部分中放置多个语句,您必须始终使用 begin-end 块。

这也是 if 语句中的一个陷阱:

if x then 
  statement1;
  statement2;  <-- statement2 will always be executed, because it's not part of the if  

这应该是:

if x then begin
  statement1;
  statement2;     <-- statement2 depends on x.
end;

正是由于这个原因,许多人总是使用开始-结束块。
即使只有一条语句。
如果您稍后更改代码,您只需将额外的语句放在已经存在的 begin-end 块中,并且不要忘记将其放入。

请注意,assignfile-reset-seek 等调用已经过时了。
在 Delphi 中,使用字符串列表进行处理会更有效。

procedure TForm1.Button3Click(Sender: TObject);
var 
  MyText: TStringList;
  i,a: integer;
  znak,tecka:char;
const
  Alpha = 'a'..'z','A'..'Z';
  Filename = 'Znaky.dat';
begin
  tecka:='.';
  MyText:= TStringlits.create;
  MyText.LoadFromFile(Filename);
  //loop though all lines.
  for i:= 0 to MyText.Lines.Count-1 do begin
    //loop though every char in a line (string chars start counting from 1 !)
    for a:= 1 to Length(MyText.Lines[i]) do begin
      case MyText.Lines[i][a] of 
        Alpha: begin
          MyText.Lines[i][a]:= tecka;
        end;
      end; {case} 
    end; {for}
  end; {for}
  MyText.WriteToFile(Filename);
end;

这更高效,因为您只需执行两次磁盘 IO,而不是多次。

个人挑剔:请不要将casewhile 之类的关键字大写,这是Pascal,而不是VB。

【讨论】:

  • @Johan:请将每个 begin 放在单独的行上,与 end 对齐。这是 Delphi,不是 Java 或 K&R C。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-15
  • 2023-01-16
  • 2011-04-19
相关资源
最近更新 更多