替换包含#0的字符串?

时间:2010-07-01 07:11:20

标签: delphi string unicode delphi-2007 utf-16

我使用此函数将文件读取到字符串

function LoadFile(const FileName: TFileName): string;
begin
  with TFileStream.Create(FileName,
      fmOpenRead or fmShareDenyWrite) do begin
    try
      SetLength(Result, Size);
      Read(Pointer(Result)^, Size);
    except
      Result := '';  
      Free;
      raise;
    end;
    Free;
  end;
end;

这是文件的文本:

version  

这是LoadFile的返回值:

'ÿþv'#0'e'#0'r'#0's'#0'i'#0'o'#0'n'#0

我想创建一个包含“verabc”的新文件。问题是我仍然有问题用“abc”替换“sion”。我正在使用D2007。如果我删除所有#0,那么结果将成为中文字符。

2 个答案:

答案 0 :(得分:8)

您认为文件的文本实际上并不是文件的文本。您在字符串变量中读到的内容是准确的。您有一个Unicode文本文件编码为little-endian UTF-16。前两个字节表示字节顺序标记,之后的每对字节都是字符串的另一个字符。

如果您正在读取Unicode文件,则应使用Unicode数据类型,例如WideString。在设置字符串的长度时,您需要将文件大小除以2,并且您将要丢弃前两个字节。

如果你不知道你正在阅读什么类型的文件,那么你需要先读取前两个或三个字节。如果前两个字节是$ ff $ fe,如上所述,那么你可能有一个小端UTF-16文件;如果您有该类型,请将文件的其余部分读入WideStringUnicodeString。如果它们是$ fe $ ff,那么它可能是大端的;将文件的其余部分读入WideString,然后交换每对字节的顺序。如果前两个字节是$ ef $ bb,则检查第三个字节。如果它是$ bf,那么它们可能是UTF-8字节顺序标记。丢弃所有三个并将文件的其余部分读入AnsiString或字节数组,然后使用UTF8Decode之类的函数将其转换为WideString

WideString中获得数据后,调试器会显示它包含version,您可以毫不费力地使用支持Unicode的StringReplace版本来执行更换。

答案 1 :(得分:0)

您似乎加载了unicode编码的文本文件。 0表示拉丁字符。

如果您不想处理unicode文本,请在保存文件时在编辑器中选择ANSI编码。

如果您需要unicode编码,请使用WideCharToString将其转换为ANSI字符串,或者只删除0 s,尽管后者不是最佳解决方案。同时删除2个前导字符ÿþ 编辑器将这些字节作为unicode放到mark文件中。