Buscar..


Tipos de cuerdas

Delphi tiene los siguientes tipos de cadena (en orden de popularidad):

Tipo Longitud maxima Talla minima Descripción
string 2GB 16 bytes Una cadena manejada. Un alias para AnsiString través de Delphi 2007 y un alias para UnicodeString partir de Delphi 2009.
UnicodeString 2GB 16 bytes Una cadena gestionada en formato UTF-16.
AnsiString 2GB 16 bytes Una cadena administrada en formato ANSI anterior a Unicode. A partir de Delphi 2009, lleva un indicador de página de código explícito.
UTF8String 2GB 16 bytes Una cadena administrada en formato UTF-8, implementada como AnsiString con una página de códigos UTF-8.
ShortString 255 caracteres 2 bytes Una cadena heredada, de longitud fija, no administrada con muy poca sobrecarga
WideString 2GB 4 bytes Diseñado para interoperabilidad COM, una cadena administrada en formato UTF-16. Equivalente al tipo BSTR Windows.

UnicodeString y AnsiString son referencias contabilizadas y copia en escritura (COW).
ShortString y WideString no se cuentan como referencia y no tienen semántica COW.

Instrumentos de cuerda

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

Los caracteres

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

La cláusula de uses debe ser System.Character si la versión es XE2 o superior.

SUPERIOR y minúscula

uses
  SysUtils;

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

Asignación

Asignación de cadenas a diferentes tipos de cadenas y cómo se comporta el entorno de ejecución con respecto a ellas. La asignación de memoria, el recuento de referencias, el acceso indexado a los caracteres y los errores del compilador se describen brevemente cuando corresponda.

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 }

Recuento de referencias

Contar referencias en cadenas es seguro para subprocesos. Se utilizan candados y controladores de excepciones para salvaguardar el proceso. Considere el siguiente código, con comentarios que indican dónde el compilador inserta el código en el momento de la compilación para administrar los recuentos de referencias:

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.

Como se muestra arriba, la introducción de una cadena local temporal para contener las modificaciones a un parámetro implica la misma sobrecarga que hacer modificaciones directamente a ese parámetro. La declaración de una cadena const solo evita el conteo de referencias cuando el parámetro de cadena es realmente de solo lectura. Sin embargo, para evitar filtrar detalles de implementación fuera de una función, es recomendable utilizar siempre uno de const , var o out en el parámetro de cadena.

Codificaciones

Los tipos de cadena como UnicodeString, AnsiString, WideString y UTF8String se almacenan en una memoria con su codificación respectiva (consulte Tipos de cadena para obtener más detalles). Asignar un tipo de cadena a otro puede resultar en una conversión. La cadena de tipo está diseñada para ser independiente de la codificación; nunca debe usar su representación interna.

La clase Sysutils.TEncoding proporciona el método GetBytes para convertir string a TBytes (matriz de bytes) y GetString para convertir TBytes a string . La clase Sysutils.TEncoding también proporciona muchas codificaciones predefinidas como propiedades de clase.

Una forma de lidiar con las codificaciones es usar solo el tipo de string en su aplicación y usar la TEncoding cada vez que necesite usar una codificación específica, generalmente en operaciones de E / S, llamadas a DLL, 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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow