Pregunta

Acabo de recibir Delphi 2009 y anteriormente leí algunos artículos sobre modificaciones que podrían ser necesarias debido al cambio a cadenas Unicode.Principalmente, se menciona que ya no se garantiza que sizeof(char) sea 1.Pero, ¿por qué sería interesante esto con respecto a la manipulación de cadenas?

Por ejemplo, si uso AnsiString:='Test' y hago lo mismo con una cadena (que ahora es Unicode), obtengo Longitud() = 4, que es correcta para ambos casos.Sin haberlo probado, estoy seguro de que todas las demás funciones de manipulación de cadenas se comportan de la misma manera y deciden internamente si el argumento es una cadena Unicode o cualquier otra cosa.

¿Por qué me interesaría el tamaño real de un carácter si hago manipulaciones de cadenas?(Por supuesto, si uso cadenas como cadenas y no para almacenar ningún otro dato)

¡Gracias por cualquier ayuda!Holger

¿Fue útil?

Solución

Con Unicode Tamaño de (algunos caracteres) <> longitud (algunos caracteres).Básicamente, la longitud de un cadena es menor que la suma del tamaño de sus carbonizarses.Mientras no asumas Tamaño de (carácter) = 1, o Tamaño de (Alguna cadena [x]) = 1 (ya que ambos son FALSO ahora) o intenta intercambiar bytees con carbonizarses, entonces no deberías tener ningún problema.Cualquier lugar donde estés haciendo algo creativo. Bytes en Carbonizarses o Cadenas, entonces necesitarás usar AnsiString.

(SizeOf(SomeString) sigue siendo 4 sin importar la longitud, ya que es esencialmente un puntero con algo de magia del compilador).

Otros consejos

La gente a menudo convierte implícitamente de caracteres a bytes en el antiguo código Delphi sin pensar realmente en ello.Por ejemplo, al escribir en una secuencia.Cuando escribes una cadena en una secuencia, debes especificar el número de bytes que escribes, pero la gente suele pasar el recuento de caracteres.Ver esta publicación de Chris Bensen para otro ejemplo.

Otra forma en que la gente suele realizar esta conversión implícita y código antiguo es mediante el uso de una "cadena" para almacenar datos binarios.En este caso, en realidad quieren bytes, pero el tipo de datos espera caracteres.D2009 tiene un mejor tipo para esto.

No probé Delphi 2009, pero estoy usando fpc, que también está cambiando lentamente a Unicode.Estoy 95% seguro de que todo lo siguiente también es válido para Delphi 2009

En fpc (cuando se admite Unicode), será así que funciones como 'longitud' tengan en cuenta la página de códigos.Por lo tanto, devolverá la longitud de la cadena como la vería un "humano".Si hay, por ejemplo, dos caracteres chinos, que ocupan dos bytes de memoria en Unicode, la longitud devolverá 2, ya que hay dos caracteres en la cadena.Pero la cadena ocupará 4 bytes de memoria.(+la memoria para el recuento de referencia y el #0 inicial, pero aparte de eso)

Lo que ya no puedes hacer es esto:

var p : pchar;
begin
  p := s[1];
  for i := 0 to length(string)-1 do
    begin
    write(p);
    inc(p);
    end;      
end;

Porque este código, en el ejemplo de dos caracteres chinos, escribirá dos caracteres incorrectos.Es decir, los dos bytes que forman parte del primer carácter "real".

En breve:Longitud() ya no devuelve la cantidad de bytes asignados para la cadena, sino la cantidad de caracteres.(Antes del cambio a Unicode, esos dos valores eran iguales entre sí)

El tamaño real de un carácter no debería importar, a menos que esté realizando la manipulación a nivel de bytes.

(Por supuesto, si uso cadenas como cadenas y no para almacenar ningún otro dato)

Ese es el punto clave, USTED no usa cadenas para otros propósitos, pero algunas personas sí lo hacen.Usan cadenas como matrices, por lo que (y eso me incluye a mí) necesitarían verificar todos esos usos para asegurarse de que no haya nada roto...

No olvidemos que hay ocasiones en las que esta conversión no es realmente deseada.Digamos, por ejemplo, para almacenar un GUID en un registro.El guid solo puede contener caracteres hexadecimales más - y corchetes... hacer que ocupen el doble de espacio puede tener un gran impacto en el código existente.Seguro que la solución simple es cambiarlos a AnsiString y lidiar con las advertencias del compilador si realiza alguna manipulación de cadenas en ellos.

Puede ser un problema si realiza llamadas a la API de Windows.O si tiene un código heredado que lo haga o dic de cadena[0] para cambiar su longitud.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top