2008-09-24 16 views
6

Acabo de recibir Delphi 2009 y he leído anteriormente algunos artículos sobre modificaciones que podrían ser necesarias debido al cambio a cadenas Unicode. En su mayoría, se menciona que sizeof (char) no se garantiza que sea 1 más. ¿Pero por qué sería esto interesante con respecto a la manipulación de cadenas?Delphi 2009 + Unicode + tamaño de char

Por ejemplo, si uso un AnsiString: = 'Test' y hago lo mismo con un String (que ahora es Unicode), entonces obtengo Length() = 4, que es correcto 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

Respuesta

5

Con Unicode SizeOf (SomeChar) <> Longitud (SomeChar). Básicamente, la longitud de una cadena es menor que la suma del tamaño de char s. Siempre y cuando no asuma sizeof (char) = 1, o SizeOf (someString [x]) = 1 (ya que ambos son FALSO ahora) o tratar de intercambiar bytes s con carbón s, entonces no deberías tener ningún problema. Cualquier lugar que está haciendo algo creativo relleno Byte s en Char s o cadena s, entonces usted tendrá que utilizar AnsiString.

(sizeof (someString) sigue siendo 4 sin importar la longitud, ya que es esencialmente un puntero con un poco de magia compilador.)

0

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

0

(Por supuesto, si uso cadenas como cadenas y no almacenar cualquier otro dato)

Ese es el punto clave, usted no utiliza cuerdas para otros fines, pero algunas personas lo hacen. Usan cadenas al igual que las matrices, por lo que (y eso me incluye a mí) necesitarían verificar todos esos usos para asegurarse de que no haya nada roto ...

+0

Tienes razón. Me confundí porque lo leí específicamente con manipulaciones de cadenas, el tamaño del carácter sería importante. Cuando uso cadenas para almacenar cualquier cosa menos cadenas, por supuesto depende de mí manejarlo correctamente. – Holgerwa

1

No probé Delphi 2009, pero estoy usando fpc, que también es cambiando a unicode lentamente. Estoy un 95% seguro de que todo lo que sigue también se aplica a Delphi 2009

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

Lo que no puede hacer más es la siguiente:

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

Debido a que este código - en el ejemplo de dos caracteres chinos - escribe los dos caracteres incorrectos. A saber, los dos bytes que forman parte del primer carácter 'real'.

En resumen: Length() 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í)

4

Las personas a menudo implícitamente convierten de caracteres a bytes en el antiguo código Delphi sin realmente pensar en ello. Por ejemplo, al escribir en una secuencia. Cuando escribe una cadena en una secuencia, debe especificar la cantidad de bytes que escribe, pero las personas suelen pasar el recuento de caracteres. Ver this post from Chris Bensen para otro ejemplo.

Otra forma en que las personas a menudo hacen esta conversión implícita y un código anterior 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 a better type for this.

0

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

0

Puede ser un problema si usted hace llamadas a la API de Windows. O si tiene código heredado que hace inc o dec de str [0] para cambiar su longitud.

Cuestiones relacionadas