2014-02-20 1 views
1

나는 ANSI 문자열을 다루는 곳에서 델파이 7 응용 프로그램을 가지고 있으며 문자 수 (바이트 수와 반대)를 계산해야합니다. 나는 항상 문자열과 관련된 Charset (코드 페이지)을 알고있다.Delphi에서 텍스트의 문자 수 (바이트 수와 반대)를 얻는 방법은 무엇입니까?

그래서 Charset (코드 페이지)을 알고 있으므로 문자 수를 얻으려면 현재 MultiByteToWideChar을 사용하고 있습니다. Charset이 문자의 대부분이 2 바이트 길이이고 단순히 Length 함수를 사용하는 중국어, 한국어 또는 일본어 문자 세트 중 하나 인 경우 유용합니다.

그러나 여전히 개의 합성 문자을 두 자로 계산하므로 하나씩 계산해야합니다. 이제 일부 합성 문자는 유니 코드 형식으로 사전 구성되어 있습니다. 즉, MB_PRECOMPOSED이 기본적으로 사용되기 때문에 하나의 문자로 올바르게 계산됩니다. 그러나 많은 문자들은 예를 들어 히브리어, 아랍어, 태국어 등의 사전 합성 된 문자로 존재하지 않으며 그 문자는 두 개로 계산됩니다.

그래서 질문은 실제로 다음과 같습니다. 복합 문자를 단일 문자로 계산하는 방법은 무엇입니까? ANSI 문자열을 Wide 문자열로 변환하여 문자 수를 계산해도 괜찮습니다. 어쨌든 MultiByteToWideChar으로 처리하고 있습니다.

답변

2

는이 같은 유니 코드 코드 포인트를 셀 수 :

function CodePointCount(P: PWideChar): Integer; 
var 
    Count: Integer; 
begin 
    Count := 0; 
    while Word(P^)<>0 do 
    begin 
    if (Word(P^)>=$D800) and (Word(P^)<=$DFFF) then 
     // part of surrogate pair 
     inc(Count) 
    else 
     inc(Count, 2); 
    inc(P); 
    end; 
    Result := Count div 2; 
end; 

이것은 당신이 언급하지 않은 문제를 다룹니다. 즉, UTF-16은 가변 폭 인코딩입니다.

그러나 이것은 UTF-16 문자열로 표현 된 글리프 수를 알려주지 않습니다. 일부 코드 포인트는 결합 문자를 나타 내기 때문입니다. 이 결합 문자는 이웃 문자와 결합하여 하나의 동일한 문자를 형성합니다. 따라서 여러 코드 포인트, 단일 글리프. 자세한 내용은 여기를 참조하십시오. http://en.wikipedia.org/wiki/Unicode_equivalence

이것은 더 어려운 문제입니다. 이를 해결하려면 각 유니 코드 코드 포인트의 의미를 완전히 이해해야합니다. 그것은 결합 캐릭터입니까? 어떻게 결합됩니까? 실제로 전용 유니 코드 라이브러리가 필요합니다. 예를 들어 ICU.

다른 제안은 ANSI 코드 페이지를 사용하여 포기하는 것입니다. 실제로 국제화에 관심이 있다면 유니 코드를 사용해야합니다.

+0

'MultiByteToWideChar'는 이미 UTF-16이 가변 길이 인코딩이며 함수와 동일한 결과를 반환한다는 사실을 다룹니다. 문자 결합을 고려하여 실제 글리프 수를 반환하는 또 다른 API 함수가있을 수 있기를 바랬습니다. 네, 유니 코드로 마이그레이션해야한다는 것을 알고 있지만, 시간이 오래 걸릴 것입니다. 그때까지는 임시 해결책이 필요합니다. 질문은 실제로 다음과 같이됩니다 : ** 델파이 7과 호환되는 간단한 유니 코드 라이브러리가 있습니까? 그리고 글리프 수를 얻기위한 간단한 기능이 있습니까? ** 아마도 Soft Gems 중 하나입니까? – jedivader

+0

ICU를 사용하십시오. 그리고 아니오, MultiByteToWideChar는 코드 포인트 수를 반환합니다. –

+0

그럼'MultiByteToWideChar'에 대해 조금 혼란스러워합니다. [documentation] (http://msdn.microsoft.com/en-us/library/windows/desktop/dd319072%28v=vs.85%29.aspx)에는 "이 값이 0이면이 함수는 필요한 버퍼 크기 (** 문자 **). 그리고 한자에 줄 경우 올바르게 계산됩니다. 내가 여기서 무엇을 놓치고 있니? – jedivader

관련 문제