2009-11-02 2 views
4

나는 Delphi 2010을 테스트 중입니다. 다음과 같은 실수를 저질렀습니다.
"096 - Construção Ltda"의이 체인을 입력하고 다른 변수로만이/할 수 있습니까? 그/그게 "096 - Construçà £ O Ltda"를 남겨주는 그 사람을 보아라.Delphi 2010의 인코딩 오류

입구 기반

001 알시 데스 주앙 페헤이라
002 Alvir Maçaneiro
003 자동 Elétrica 이마무라 LTDA
004 자동 Peças 아라 우호
005 자동 Peças 포르투 Eixo LTDA
006 자동 Peças União
007 Azambuja Industria Comercio de Comateriois de Construção Ltda 008 Balaroti 메르시오 드 Materiais 드 CONSTRUCAO LTDA
009 Baldissera LOGISTICA 전자 TRANSPORTES LTDA 나
010 Battistella Veículos Pesados ​​LTDA
011 BERTON 디젤 자동차 Peças
012 Bisolo Materiais 드 CONSTRUCAO 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 - 알시 데스 주앙 £ 페레이라 오
002 - Alvir Maçaneiro
003 - 자동 ELA ©의 trica 이마무라 LTDA
004 - 자동 Peças Araújo
005 - 자동 Peças 포르투 Eixo LTDA
006 - 자동 Peças UNIA £ O
007 - Azambuja하기 Industria 메르시오 드 Materiais 드 Construçà £ LTDA 오
008 - Balaroti 메르시오 드 Materiais 드 Construçà £ LTDA
009 오 - Baldissera LogÃstica 전자 TRANSPORTES LTDA 나
010 - Battistella Veículos Pesados LTDA
011 - BERTON 디젤 자동 Peças 012 - LTDA
오 Bisolo Materiais 드 Construçà £

+0

두 번째 문자열은 첫 번째 문자열의 UTF-8 인코딩 형식입니다. 문자열 값을 UTF8String 변수에 할당하고 있습니까? 문제가있는 실제 코드를 보여주십시오. –

+0

문자열 값은 UTF-8로 인코딩됩니다. 유니 코드를 지원하지 않는 구형 파스칼 파일 I/O를 사용했기 때문에 그런 것 같습니다. TStringList에 파일을 로딩 한 다음 그 파일을 반복하는 것과 같은 새로운 스타일의 VCL 스타일 파일 I/O를 대신 사용하는 것이 좋습니다. 그리고 다음에 StackOverflow의 코드 포맷팅 기능을 사용하십시오. –

답변

4

이 AssignFile을 사용하지 마십시오. 레거시 코드이며 유니 코드 문자열에서는 작동하지 않습니다. 대신 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; 

이 함수는 유니 코드를 처리 할 수있다. e 문자열 (BOM 포함) 및 또한 ansistring. 사실, 그것은 당신이 가진 모든 종류의 텍스트 파일을 읽을 수 있습니다.

+1

BOM이없는 경우 파일 인코딩이 기본 인코딩 인 경우에만 작동합니다. 추가 인코딩과 함께 오버로드를 사용합니다 : TEncoding 매개 변수 (물론 파일 인코딩을 알아야합니다. 그렇지 않으면 심각한 문제가 될 것입니다) – mjn

+0

+1; 구식 파일 처리 루틴 ('AssignFile','Reset','Read','ReadLn','Write','WriteLn','Close')은 유니 코드에서 작동하지 않습니다. –

+0

@mjn 네, 맞습니다. 나는 그것을 단순하게하는 법을 보여주고 싶었다. –

관련 문제