Embarcadero Delphi
문자열
수색…
문자열 유형
Delphi에는 다음과 같은 문자열 유형이 있습니다 (인기도 순).
유형 | 최대 길이 | 최소 크기 | 기술 |
---|---|---|---|
string | 2GB | 16 바이트 | 관리되는 문자열입니다. Delphi 2009를 통한 AnsiString 의 별칭 및 Delphi 2009의 UnicodeString 별칭. |
UnicodeString | 2GB | 16 바이트 | UTF-16 형식의 관리되는 문자열입니다. |
AnsiString | 2GB | 16 바이트 | 유니 코드 이전 ANSI 형식의 관리되는 문자열입니다. Delphi 2009부터는 명시적인 코드 페이지 표시기가 있습니다. |
UTF8String | 2GB | 16 바이트 | UTF-8 형식의 관리되는 문자열이며 UTF-8 코드 페이지가있는 AnsiString 으로 구현됩니다. |
ShortString | 255 자 | 2 바이트 | 오버 헤드가 거의없는 레거시, 고정 길이, 비 관리 문자열 |
WideString | 2GB | 4 바이트 | UTF-16 형식의 관리되는 문자열 인 COM interop 용입니다. Windows BSTR 유형과 동일합니다. |
UnicodeString
및 AnsiString
은 참조 카운트 및 COW ( copy-on-write )입니다.
ShortString
과 WideString
은 참조 카운트가 아니며 COW 의미를 가지고 있지 않습니다.
문자열
uses
System.Character;
var
S1, S2: string;
begin
S1 := 'Foo';
S2 := ToLower(S1); // Convert the string to lower-case
S1 := ToUpper(S2); // Convert the string to upper-case
챠리스
uses
Character;
var
C1, C2: Char;
begin
C1 := 'F';
C2 := ToLower(C1); // Convert the char to lower-case
C1 := ToUpper(C2); // Convert the char to upper-case
uses
절은 버전이 XE2 이상인 경우 System.Character
여야합니다.
대문자와 소문자
uses
SysUtils;
var
S1, S2: string;
begin
S1 := 'Foo';
S2 := LowerCase(S1); // S2 := 'foo';
S1 := UpperCase(S2); // S1 := 'FOO';
할당
문자열을 다른 문자열 유형에 할당하고 런타임 환경이 해당 문자열 유형에 대해 어떻게 작동하는지 설명합니다. 메모리 할당, 참조 카운팅, 문자에 대한 색인 된 액세스 및 적용 가능한 경우 간략하게 설명 된 컴파일러 오류.
var
SS5: string[5]; {a shortstring of 5 chars + 1 length byte, no trailing `0`}
WS: Widestring; {managed pointer, with a bit of compiler support}
AS: ansistring; {ansistring with the default codepage of the system}
US: unicodestring; {default string type}
U8: UTF8string;//same as AnsiString(65001)
A1251: ansistring(1251); {ansistring with codepage 1251: Cryllic set}
RB: RawbyteString; {ansistring with codepage 0: no conversion set}
begin
SS5:= 'test'; {S[0] = Length(SS254) = 4, S[1] = 't'...S[5] = undefined}
SS5:= 'test1'; {S[0] = 5, S[5] = '1', S[6] is out of bounds}
SS5:= 'test12'; {compile time error}
WS:= 'test'; {WS now points to a constant unicodestring hard compiled into the data segment}
US:= 'test'+IntToStr(1); {New unicode string is created with reference count = 1}
WS:= US; {SysAllocateStr with datacopied to dest, US refcount = 1 !}
AS:= US; {the UTF16 in US is converted to "extended" ascii taking into account the codepage in AS possibly losing data in the process}
U8:= US; {safe copy of US to U8, all data is converted from UTF16 into UTF8}
RB:= US; {RB = 'test1'#0 i.e. conversion into RawByteString uses system default codepage}
A1251:= RB; {no conversion takes place, only reference copied. Ref count incremented }
참조 카운팅
문자열에 대한 참조 계산은 스레드로부터 안전합니다. 잠금 및 예외 핸들러는 프로세스를 보호하는 데 사용됩니다. 컴파일러가 참조 카운트를 관리하기 위해 컴파일 타임에 코드를 삽입하는 위치를 나타내는 주석과 함께 다음 코드를 고려하십시오.
procedure PassWithNoModifier(S: string);
// prologue: Increase reference count of S (if non-negative),
// and enter a try-finally block
begin
// Create a new string to hold the contents of S and 'X'. Assign the new string to S,
// thereby reducing the reference count of the string S originally pointed to and
// brining the reference count of the new string to 1.
// The string that S originally referred to is not modified.
S := S + 'X';
end;
// epilogue: Enter the `finally` section and decrease the reference count of S, which is
// now the new string. That count will be zero, so the new string will be freed.
procedure PassWithConst(const S: string);
var
TempStr: string;
// prologue: Clear TempStr and enter a try-finally block. No modification of the reference
// count of string referred to by S.
begin
// Compile-time error: S is const.
S := S + 'X';
// Create a new string to hold the contents of S and 'X'. TempStr gets a reference count
// of 1, and reference count of S remains unchanged.
TempStr := S + 'X';
end;
// epilogue: Enter the `finally` section and decrease the reference count of TempStr,
// freeing TempStr because its reference count will be zero.
위에서 보인 것처럼 매개 변수에 수정 사항을 보유하기 위해 임시 로컬 문자열을 도입하면 해당 매개 변수에 직접 수정하는 것과 동일한 오버 헤드가 발생합니다. 문자열 const
선언하면 문자열 매개 변수가 실제로 읽기 전용 일 때만 참조 횟수가 계산되지 않습니다. 그러나 함수 외부에서 구현 세부 사항이 누설되지 않도록하려면 항상 문자열 매개 변수에 const
, var
또는 out
중 하나를 사용하는 것이 좋습니다.
인코딩
UnicodeString, AnsiString, WideString 및 UTF8String과 같은 문자열 유형은 해당 인코딩을 사용하여 메모리에 저장됩니다 (자세한 내용은 문자열 유형 참조). 한 유형의 문자열을 다른 유형에 할당하면 변환이 발생할 수 있습니다. 유형 문자열은 독립적으로 인코딩되도록 설계되었으므로 절대 내부 표현을 사용하지 않아야합니다.
Sysutils.TEncoding
클래스는 string
을 TBytes
(바이트 배열)로 변환하는 GetBytes
메서드와 TBytes
를 string
변환하는 GetString
메서드를 제공 string
. Sysutils.TEncoding
클래스는 미리 정의 된 많은 인코딩을 클래스 속성으로 제공합니다.
인코딩을 다루는 한 가지 방법은 응용 프로그램에서 string
유형 만 사용하고 일반적으로 I / O 작업, DLL 호출 등의 특정 인코딩을 사용해야 할 때마다 TEncoding
을 사용하는 것입니다.
procedure EncodingExample;
var hello,response:string;
dataout,datain:TBytes;
expectedLength:integer;
stringStream:TStringStream;
stringList:TStringList;
begin
hello := 'Hello World!Привет мир!';
dataout := SysUtils.TEncoding.UTF8.GetBytes(hello); //Conversion to UTF8
datain := SomeIOFunction(dataout); //This function expects input as TBytes in UTF8 and returns output as UTF8 encoded TBytes.
response := SysUtils.TEncoding.UTF8.GetString(datain); //Convertsion from UTF8
//In case you need to send text via pointer and length using specific encoding (used mostly for DLL calls)
dataout := SysUtils.TEncoding.GetEncoding('ISO-8859-2').GetBytes(hello); //Conversion to ISO 8859-2
DLLCall(addr(dataout[0]),length(dataout));
//The same is for cases when you get text via pointer and length
expectedLength := DLLCallToGetDataLength();
setLength(datain,expectedLength);
DLLCall(addr(datain[0]),length(datain));
response := Sysutils.TEncoding.GetEncoding(1250).getString(datain);
//TStringStream and TStringList can use encoding for I/O operations
stringList:TStringList.create;
stringList.text := hello;
stringList.saveToFile('file.txt',SysUtils.TEncoding.Unicode);
stringList.destroy;
stringStream := TStringStream(hello,SysUtils.TEncoding.Unicode);
stringStream.saveToFile('file2.txt');
stringStream.Destroy;
end;