2011-03-08 4 views

답변

11

이 같은 기능은 당신이 필요로 할 것입니다 :

function UTF8Bytes(const s: UTF8String): TBytes; 
begin 
    Assert(StringElementSize(s)=1); 
    SetLength(Result, Length(s)); 
    if Length(Result)>0 then 
    Move(s[1], Result[0], Length(s)); 
end; 

당신은 문자열의 모든 유형을 호출 할 수 있고, RTL은 UTF-8로 전달되는 문자열의 인코딩 변환됩니다. 그러니 전화하기 전에 UTF-8로 변환해야한다는 생각에 속아서는 안됩니다. 그냥 문자열을 전달하고 RTL로 작업하게하십시오.

그 다음은 상당히 표준적인 배열 사본입니다. UTF-8로 인코딩 된 문자열의 문자열 요소 크기에 대한 가정을 명시 적으로 호출하는 어설 션에 유의하십시오. 당신이 제로 터미네이터를 얻고 싶다면

그렇게를 작성합니다

function UTF8Bytes(const s: UTF8String): TBytes; 
begin 
    Assert(StringElementSize(s)=1); 
    SetLength(Result, Length(s)+1); 
    if Length(Result)>0 then 
    Move(s[1], Result[0], Length(s)); 
    Result[high(Result)] := 0; 
end; 
+0

+1. Assert (StringElementSize (s) = 1);이 실패합니까? –

+1

@Cosmin 아니요. 그것은 단언에 관한 것입니다! –

+0

한 가지 질문 .. StringElementSize()? (lazarus)를 사용하려면 어떤 단위를 추가해야합니까? 그런 질문에 대해 미안하다, 초보자이다. – Mariusz

4
var S: UTF8String; 
    B: TBytes; 

begin 
    S := 'Șase sași în șase saci'; 
    SetLength(B, Length(S)); // Length(s) = 26 for this 22 char string. 
    CopyMemory(@B[0], @S[1], Length(S)); 
end. 

바이트가 필요한 항목에 따라 NULL 종결자를 포함 할 수 있습니다.

생산 코드의 경우 빈 문자열을 테스트해야합니다. 3-4 LOC를 추가하면 샘플을 읽기가 더 어려워집니다.

+0

문자열이 비어 있으면 실패합니다. –

+1

문자열이 비어 있지 않습니다. 여기에는''şase saşi în şase saci ''값 –

+0

+1이 들어 있습니다. 모두는 (최소한을 말하기 위해!)'Length' 함수가 실제로 어떻게 작동 하는지를 안다! –

8

당신은 나중에 델파이 2009 이상을 사용하는 경우 SysUtils.pas

+0

+1을 참조하십시오. 이것이 최선의 방법입니다. –

+5

입력 문자열이 * 이미 UTF-8로 인코딩되어 있으면'GetBytes'가 매우 낭비됩니다. 컴파일러는 입력 문자열을 UnicodeString으로 변환합니다. GetBytes가 허용하는 유일한 문자열 인수이므로 GetBytes는 해당 문자를 UTF-8로 변환하여 결과를 생성합니다. –

5

을에 TEncoding.UTF8.GetBytes을 사용할 수 있습니다 (유니 코드 버전)하는 UTF8String에에 WideString으로 변환하는 것은 단순한 할당 문입니다 :

var 
    ws: WideString; 
    u8s: UTF8String; 

u8s := ws; 

이 일을 알고 있기 때문에 변환을 할 수있는 권리 라이브러리 함수를 호출합니다 컴파일러 UTF8String 유형의 값에는 CP_UTF8의 "코드 페이지"가 ​​있습니다.

Delphi 7 이상에서는 제공된 라이브러리 함수 Utf8Encode을 사용할 수 있습니다. 이전 버전의 경우에도 JCL과 같은 다른 라이브러리에서이 기능을 사용할 수 있습니다.

또한 윈도우 API 사용하여 자신의 변환 기능을 쓸 수 있습니다 :

function CustomUtf8Encode(const ws: WideString): UTF8String; 
var 
    n: Integer; 
begin 
    n := WideCharToMultiByte(cp_UTF8, 0, PWideChar(ws), Length(ws), nil, 0, nil, nil); 
    Win32Check(n <> 0); 
    SetLength(Result, n); 
    n := WideCharToMultiByte(cp_UTF8, 0, PWideChar(ws), Length(ws), PAnsiChar(Result), n, nil, nil); 
    Win32Check(n = Length(Result)); 
end; 

많은 시간, 당신은 단순히 배열로 UTF8String에 사용할 수 있습니다,하지만 당신이 정말로 바이트 배열을해야하는 경우 David와 Cosmin의 기능을 사용할 수 있습니다. 자신 만의 문자 변환 기능을 작성하는 경우 UTF8String을 건너 뛰고 바이트 배열로 직접 이동할 수 있습니다. 리턴 유형을 TBytes 또는 array of Byte으로 변경하십시오. 배열을 null로 종료하려면 길이를 1 씩 늘리십시오. SetLength는 암시 적으로 문자열로하지만 배열로 처리합니다.

다른 문자열 유형이있는 경우 WideString, UnicodeString 또는 UTF8String이 아닌 경우 UTF-8로 변환하는 방법은 먼저 WideString 또는 UnicodeString으로 변환 한 다음 UTF-8로 다시 변환하는 것입니다.

1

나는 다음과 같은 두 가지 루틴 (소스 코드는 여기에서 다운로드 할 수 있습니다 - http://www.csinnovations.com/framework_utilities.htm)을했다 :

기능 CsiBytesToStr (const를 pInData : TByteDynArray, pStringEncoding : TECsiStringEncoding, pIncludesBom : 부울) : 문자열;

function CsiStrToBytes (const pInStr : string; pStringEncoding : TECsiStringEncoding; pIncludeBom : 부울) : TByteDynArray;

관련 문제