Reputation: 13
Hi, im currently working with files. Its File of Char that is declared globally. Im trying to find any letter (A,b, etc.) in the file of char and i know there is only one character in each line and i want to change it to dot. (Variable TECKA - DOT) When i want to write char, it says "Constant expression expected", but when i change it to constant (code in comment section), it says "Variable required". What am i doing wrong here? Thanks for reply.
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;
Upvotes: 0
Views: 394
Reputation: 76537
What you're doing wrong has nothing to do with the line write(f,tecka);
, but everything to do with block rules in pascal.
If you want to compiler to stop complaining you need to change the case statement to:
case znak of
'a'..'z','A'..'Z': begin
seek(f,filepos(f)-1);
write(f,tecka);
end;
end; {case}
The problem is that the case statement expects one or more constant expressions (e.g. 'a'..'z'
) after the of
. After a :
you can only put a single statement or a begin end block. Because you're putting 2 statements after the :
Pascal wants to interpret the second statement as another case clause (e.g.: '0'..'9':
) which it isn't.
If you want to put multiple statements in a section you must always use a begin-end block.
This is also a gotcha in if-statements:
if x then
statement1;
statement2; <-- statement2 will always be executed, because it's not part of the if
This should be:
if x then begin
statement1;
statement2; <-- statement2 depends on x.
end;
It's for this reason that many people always use begin-end blocks.
Even if there is a single statement.
If you change code later you just put your extra statements in the begin-end block that's already there and you can't forget to put it in.
Note that the assignfile-reset-seek etc calls are quite outdated.
In Delphi it's more efficient to use a stringlist to do your processing.
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;
This is more performant because you only do disk IO twice instead of many times.
Personal nitpick: please don't capitalize keywords like case
and while
, this is Pascal, not VB.
Upvotes: 4