0

I am trying to get this code to work. It's a standard search and replace function.

I get no errors at all but nothing changes in the text file for some reason.

Here is the full code:

procedure FileReplaceString(const FileName, searchstring, replacestring: string);
var
  fs: TFileStream;
  S: string;
begin
  fs := TFileStream.Create(FileName, fmOpenread or fmShareDenyNone);
  try
    SetLength(S, fs.Size);
    fs.ReadBuffer(S[1], fs.Size);
  finally
    fs.Free;
  end;
  S  := StringReplace(S, SearchString, replaceString, [rfReplaceAll, rfIgnoreCase]);
  fs := TFileStream.Create(FileName, fmCreate);
  try
    fs.WriteBuffer(S[1], Length(S));
  finally
    fs.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
  var Path, FullPath:string;
begin
  Path:= ExtractFilePath(Application.ExeName);
  FullPath:= Path + 'test.txt';
  FileReplaceString(FullPath,'changethis','withthis');

end;
Satch3000
  • 47,356
  • 86
  • 216
  • 346
  • 1
    `S` is a Unicode string, while the data in the text file probably is ASCII or UTF-8. I bet it works if you declare `S` as `AnsiString` instead. – Andreas Rejbrand Apr 21 '13 at 19:41
  • Your question does not mention your delphi version and yet your whole problem is that you are not aware of Delphi versions, including the fact that starting at Delphi 2009, the meaning of String changed from AnsiString to UnicodeString, leading to this, and all manner of other similar confusions. It would be better if you had read some documentation! – Warren P Apr 21 '13 at 21:28

1 Answers1

7

The reason is that S, searchstring, and replacestring are Unicode strings (so, e.g., "Test" is 54 00 65 00 73 00 74 00) while the text file probably is a UTF-8 or ANSI file (so, e.g., "Test" is 54 65 73 74).

This means that the value stored in S will be highly corrupt (you take the bytes of a UTF-8 text and interpret them as the bytes of a Unicode text)! In the Test example, you will get 敔瑳?? where the two last characters are random (why?).

To test this hypothesis, simply declare S as AnsiString instead, then it should work.

Of course, if you need Unicode support, you need to do some UTF-8 encoding/decoding. The simplest solution to your problem would be to use the TStringList; then you get everything you need for free.

Andreas Rejbrand
  • 105,602
  • 8
  • 282
  • 384