2010-04-01 3 views
4

D2006 프로그램을 D2010으로 변환 중입니다. 데이터베이스의 문자열 당 하나의 바이트에 하나의 값을 저장하고 LoadFromStream이있는 컨트롤에로드해야하므로 내 문자열을 스트림에 쓰고 LoadFromStream과 함께 사용해야합니다. 그러나 그것은 효과가 없었습니다. 이 문제를 연구하면서 AnsiString에서 Unicode 문자열로의 변환이 실제로 어떻게 작동하는지 이해하지 못한다는 것을 알게되었습니다. 다음은 내가 혼란스러워하는 문제를 보여주는 독립 실행 형 코드입니다. AnsiString을 유니 코드 문자열로 변환

procedure TForm1.Button1Click(Sender: TObject); {$O-} 
var 
    sBuffer: String; 
    oStringStream: TStringStream; 
    sAnsiString: AnsiString; 
    sUnicodeString: String; 
    iSize1, 
    iSize2: Word; 
begin 
    sAnsiString := '12345'; 
    oStringStream := TStringStream.Create(sBuffer); 
    sUnicodeString := sAnsiString; 
    iSize1 := StringElementSize(sAnsiString); 
    iSize2 := StringElementSize(sUnicodeString); 
    oStringStream.WriteString(sUnicodeString); 
end; 

마지막 줄에 중단하고, oStringStream의 바이트 속성을 검사하는 경우

, 당신은 다음과 같습니다 것을 볼 수 있습니다 :

Bytes (49 {$31}, 50 {$32}, 51 {$33}, 52 {$34}, 53 {$35} 

나는 그것이

처럼 보일 수 있음을 예상하고 있었다
(49 {$31}, 00 {$00}, 50 {$32}, 00 {$00}, 51 {$33}, 00 {$00}, 
52 {$34}, 00 {$00}, 53 {$35}, 00 {$00} ... 

분명히 내 기대치가 잘못되었습니다. 그렇다면 AnsiString을 유니 코드로 변환하는 방법은 무엇입니까?

한 번에 스트림에서 2 바이트를 읽으므로 올바른 결과를 얻지 못하고 있지만받는 데이터가 그런 방식으로 정렬되어 있지 않습니다. LoadFromStream에 유니 코드 문자열 기반의 데이터 스트림을 제공하려면 어떻게해야합니까?

도움 주셔서 감사합니다.

+3

나는 의미있는 대답을하기에 충분한 정보가 질문에 있다고 생각하지 않습니다. 변수에는 어떤 유형이 관련되어 있습니까? 이는 컴파일러가 생성 한 코드에서 트리거되는 자동 변환과 관련하여 잠재적으로 중요합니다. 또한 특히 oPayGrid의 유형은 무엇입니까? 이 객체에 sStream 속성이 있으면 표준 VCL 스트림이 아님을 알 수 있습니다. 이상적으로는 문제의 코드 예제가 추가 설명/점에 대한 필요없이 동작을 보여주는 독립 실행 형 예제로 재 작성/확장되었습니다. – Deltics

+0

아오 테아 로아에 우박! 죄송합니다. 나는 도움이되지 않는 세부 사항으로 질문을 혼란스럽게하는 것을 피하려고 노력했다. 나는 내가 너무 성공적이었다고 생각한다. oPaygrid는 클래스 (TObject)입니다. oPaygrid.sStream의 이름이 AnsiString입니다. sUnicodeString은 기본적으로 유니 코드 문자열 인 Delphi 문자열입니다. iSize1과 iSize2는 정수입니다. 내 질문은 주로 개념적입니다. AnsiString을 유니 코드 문자열로 캐스팅 할 때 유니 코드 문자열에 문자 당 2 바이트가 표시되어야합니까? 나는 그것을 보지 못하고 있으며 LoadFromStream으로 내 컨트롤을 성공적으로로드하지 못하게하는 것 같습니다. – jrodenhi

+0

StringElementSize()를 사용하면 안됩니다. 반 이주 된 C++ Builder 모듈에서 코드를 호출하는 경우에만 필요합니다. 할당'sUnicodeString : = sAnsiString'은 문자열의 페이로드를 Char = WideChar로 수정하여 StringElementSize에 대한 호출은 항상 AnsiString의 SizeOf (AnsiChar)를 반환하고 UnicodeString의 SizeOf (Char)를 반환합니다. SizeOf (AnsiChar)/SizeOf (Char)는 훨씬 빠르고 빠르며 읽기 쉽고 이해하기 쉽고 글자가 짧습니다. –

답변

5

oStringStream.WriteString 매개 변수의 유형은 무엇입니까? AnsiString이면 유니 코드에서 Ansi 로의 암시 적 변환이 있으며 이는 사용자의 예제를 설명합니다.


업데이트 : 이제 진짜 질문은 TStringStream이 데이터를 내부적으로 저장하는 방법입니다. 다음의 코드 샘플 (2,009 델파이)

procedure TForm1.Button1Click(Sender: TObject); 
var 
    S: string; 
    SS: TStringStream; 

begin 
    S:= 'asdfg'; 
    SS:= TStringStream.Create(S); // 1 byte per char 
    SS.WriteString('321'); 
    Label1.Caption:= SS.DataString; 
    SS.Free; 
end; 

TStringStream 내부적 기본 시스템 ANSI 인코딩 (문자 당 1 바이트)를 사용한다. constructor 및 WriteString 프로시 저는 문자열 인수를 유니 코드에서 ANSI로 변환합니다. 당신의 단일 바이트 문자를 ASCII가 아니라 기반으로하는 경우

LoadFromStream(stream, TEncoding.ASCII); 

:

procedure TForm1.Button1Click(Sender: TObject); 
var 
    S: string; 
    SS: TStringStream; 

begin 
    S:= 'asdfg'; 
    SS:= TStringStream.Create(S, TEncoding.Unicode); // 2 bytes per char 
    SS.WriteString('321'); 
    Label1.Caption:= SS.DataString; 
    SS.Free; 
end; 
+0

sBuffer는 다음과 같이 선언됩니다. var sBuffer : UnicodeString; – jrodenhi

0

내가 사용하려는 생각 :

당신이 명시 적으로 생성자에서 인코딩을 선언해야이 동작을 재정의하려면 코드 페이지에서 다음과 같이 작동 할 수 있습니다.

LoadFromStream(stream, TEncoding.GetEncoding(1252)); 

여기서 "1252"는 코드 페이지입니다. ur 단일 바이트 텍스트가 기반으로합니다.

+0

LoadFromStream은 TMS의 AdvStringrid 메소드입니다. 매개 변수 하나만 필요합니다. – jrodenhi

+0

TMS는 사용하지 않지만 TMS의 TTntStringGrid는 유니 코드 구성 요소 팩에 포함되어 있습니다. 참조 : http://www.tmssoftware.com/site/tmsuni.asp 그렇지 않으면 TMS에 연락하여 문제를 알려주고 두 번째 매개 변수를 LoadFromStream에 추가하여 Delphi 2009+ 유니 코드와 호환되도록 할 수 있습니다. . – lkessler

+0

이것은 그리드에 문제가없는 것 같습니다. 제 원래 게시물의 편집 내용을 확인하십시오. Unicode에 AnsiString을 캐스팅하면 문자열의 내부 형식이 변경되는 것으로 보이지 않습니다. – jrodenhi

0

스트림 형식은 주로 TStringStream.Encoding에 따라 다릅니다. 귀하의 예제에서 사용 된 코드 페이지는 sBuffer와 동일해야합니다 (TStringStream.Create의 암시를 참조하십시오).

oStringStream.WriteString(sUnicodeStream);은 단일 바이트로 저장되는 것으로 보이므로 sBuffer는 Ansistring 또는 RawByteString으로 가정합니다.

이제 ... 왜 읽는 데 실패합니까? 당신은 우리가 그 스트림에서 다시 읽는 방법에 대한 예제를 아직주지 못했습니다.

+0

나처럼, sUnicodeStream이 UnicodeString으로 선언되면 문자 당 2 바이트로 구성된 문자열을 보게 될 것이라고 예상 할 수 있습니다. 새로 편집 한 예제 코드를 시험해 보면 분명히 그런 식으로 작동하지 않는다는 것을 알 수 있습니다. – jrodenhi

+0

Serg is right ... TStringStream은 ansistring 버전의 코드 페이지 만 검사합니다. –

관련 문제