Delphi 2010中的编码错误

4

我正在测试Delphi 2010,但遇到了以下错误:
当我输入字符“096 - Construção Ltda”并将其移动到另一个变量中时,发现它变成了“096 - Construção Ltda”,有人知道怎么解决吗?

输入基础

001 Alcides João Pereira
002 Alvir Maçaneiro
003 Auto Elétrica Imamura Ltda
004 Auto Peças Araújo
005 Auto Peças Porto Eixo Ltda
006 Auto Peças União
007 Azambuja Industria Comercio de Materiais de Construção Ltda
008 Balaroti Comercio De Materiais De Construção Ltda
009 Baldissera Logística e Transportes Ltda Me
010 Battistella Veículos Pesados Ltda
011 Berton Diesel Auto Peças
012 Bisolo Materiais de Construção Ltda

procedure TForm1.Button2Click(Sender: TObject);
var
   tfEntrada : TextFile;
   intI, intJ : Integer;
   strA, strS : String;

   procedure lerUm; //To read a registration of the file text
   begin
      inc( intI );
      ReadLn( tfEntrada, strS );

      strA := Copy( IntToStr( intI + 1000 ), 2, 3 ) + ' - ';
      Edit1.Text := strS;

   end;

begin

   intI := 0;
   AssignFile( tfEntrada, 'nomes_tst_0001.txt' );
   Reset( tfEntrada );

   lerUm;

   while not Eof ( tfEntrada ) do
   begin

     mmEntrada.Lines.Add( strA + strS ); //I move for TMemo(mmEntrada, mmSaida), in the form

     mmSaida.Lines.Add( strA + strS );

     lerUm;

  end;

  CloseFile( tfEntrada );

end;

结果基础

001 - Alcides João Pereira
002 - Alvir Maçaneiro
003 - Auto Elétrica Imamura Ltda
004 - Auto Peças Araújo
005 - Auto Peças Porto Eixo Ltda
006 - Auto Peças União
007 - Azambuja Industria Comercio de Materiais de Construção Ltda
008 - Balaroti Comercio De Materiais De Construção Ltda
009 - Baldissera Logística e Transportes Ltda Me
010 - Battistella Veículos Pesados Ltda
011 - Berton Diesel Auto Peças 012 - Bisolo Materiais de Construção Ltda


请注意,本文中的特殊字符已被正确转换。

第二个字符串是第一个字符串的UTF-8编码形式。你是否将你的字符串值分配给了一个UTF8String变量?请展示你遇到问题的实际代码。 - Remy Lebeau
您的字符串值仍在使用UTF-8进行编码。我怀疑这是因为您使用了旧式Pascal文件I/O,它不支持Unicode。我强烈建议您改用新式VCL-style文件I/O,例如通过将文件加载到TStringList中,然后循环遍历该列表。下次请使用StackOverflow的代码格式化功能。 - Remy Lebeau
1个回答

4

不要使用AssignFile。它是遗留代码,不支持UnicodeStrings。相反,使用TStringList或TFileStream读取文件。

[未经测试]

procedure ReadFile;  
var  
  vFileReader : TstringList;  
begin  
  vFileReader := TStringList.Create;  
  try
    vFileReader.LoadFromFile('nomes_tst_0001.txt');  
    mmEntrada.Lines.Assign(vFileReader);  
  finally
    vFileReader.Free;  
  end;
end;

已编辑

另一个不错的解决方案是我很久以前写的关注函数:

[已测试]

function GetFileAsString(aFileName: string; aOffSet : Integer = 0; aChunkSize: Integer = -1): string;
var
  vStream: TFileStream;
  vBuffer: TBytes;
  vCurEncoding, vDefEncoding: TEncoding;
  vOffSet: Integer;
  vFileSize: Int64;
begin
  vCurEncoding := nil;
  vDefEncoding := TEncoding.Default;
  vStream := TFileStream.Create(aFileName, fmOpenRead + fmShareDenyNone);
  try
    if aChunkSize > 0 then begin
      vFileSize := aChunkSize;
    end
    else begin
      vFileSize := vStream.Size;
    end;
    vStream.Position := aOffSet;
    SetLength(vBuffer, vFileSize);
    vStream.ReadBuffer(Pointer(vBuffer)^, vFileSize);
    vOffSet := TEncoding.GetBufferEncoding(vBuffer, vCurEncoding);
    if (vCurEncoding <> vDefEncoding) then begin
      vBuffer := TEncoding.Convert(vCurEncoding, vDefEncoding, vBuffer, vOffSet,   vFileSize - vOffSet);
    end;
    Result := vDefEncoding.GetString(vBuffer);
  finally
    vStream.Free;
  end;
end;

这个函数可以处理带有BOM的Unicode字符串和ansistring。实际上,它可以读取您拥有的所有类型的文本文件。


1
只有当文件编码是默认编码时(除非有BOM),这才能正常工作。我会使用带有额外Encoding:TEncoding参数的重载(当然,我需要知道文件编码,否则我会遇到严重问题)。 - mjn
+1; 旧式文件处理例程(AssignFileResetReadReadLnWriteWriteLnClose)不支持Unicode。 - Jeroen Wiert Pluimers
@mjn 是的,你说得对。我只是想展示如何简单地完成它。 - Rafael Colucci
1
@Jeroen:嗯,它们确实可以使用Unicode,只需要显式地进行编码/解码即可。 - Andreas Rejbrand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接