Sök…


Strängtyper

Delphi har följande strängtyper (i popularitetsordning):

Typ Maximal längd Minsta storlek Beskrivning
string 2GB 16 byte En hanterad sträng. Ett alias för AnsiString och med Delphi 2007 och ett alias för UnicodeString från och med Delphi 2009.
UnicodeString 2GB 16 byte En hanterad sträng i UTF-16-format.
AnsiString 2GB 16 byte En hanterad sträng i ANSI-format före Unicode. Från Delphi 2009 har den en tydlig kodsidaindikator.
UTF8String 2GB 16 byte En hanterad sträng i UTF-8-format, implementerad som en AnsiString med en UTF-8-kodsida.
ShortString 255 tecken 2 byte En arv, fast längd, okontrollerad sträng med mycket lite overhead
WideString 2GB 4 bytes Avsedd för COM interop, en hanterad sträng i UTF-16-format. Motsvarande med Windows BSTR typ.

UnicodeString och AnsiString är referensräknade och copy-on-write (COW).
ShortString och WideString är inte referensräknade och har inte COW-semantik.

strängar

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

tecken

2009
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 ska vara System.Character om versionen är XE2 eller högre.

ÖVER- och gemener

uses
  SysUtils;

var
  S1, S2: string;
begin
  S1 := 'Foo';
  S2 := LowerCase(S1); // S2 := 'foo';
  S1 := UpperCase(S2); // S1 := 'FOO';

Uppdrag

Tilldela sträng till olika strängtyper och hur runtime-miljön beter sig. Minnesallokering, referensräkning, indexerad tillgång till tecken och kompilatorfel beskrivs kort där det är tillämpligt.

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 }

Referensräkning

Att räkna referenser på strängar är tråd-säkert. Lås och undantagshanterare används för att skydda processen. Tänk på följande kod, med kommentarer som anger var kompilatorn sätter in kod vid sammanställningstiden för att hantera referensräkningar:

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.

Som visas ovan innebär introduktion av tillfällig lokal sträng för att hålla modifieringarna till en parameter samma overhead som att göra ändringar direkt till den parametern. Deklarera en sträng const bara undviker referensräkning när strängen parametern verkligen skrivskyddad. För att undvika läckande implementeringsdetaljer utanför en funktion rekommenderas det dock alltid att använda en av const , var eller out på strängparametern.

kodningar

Strängtyper som UnicodeString, AnsiString, WideString och UTF8String lagras i ett minne med deras respektive kodning (se Stringtyper för mer information). Tilldelning av en typ av sträng till en annan kan resultera i en konvertering. Typsträngen är utformad så att den kodar oberoende - du får aldrig använda den interna representationen.

Klassen Sysutils.TEncoding tillhandahåller metod GetBytes för konvertering av string till TBytes (matris med byte) och GetString för konvertering av TBytes till string . Klassen Sysutils.TEncoding ger också många fördefinierade kodningar som klassegenskaper.

Ett sätt att hantera kodningar är att använda endast string i din applikation och använda TEncoding varje gång du behöver använda specifik kodning - vanligtvis i I / O-operationer, DLL-samtal, etc. ...

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;


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow