[Lazarus-es] Problemas con strings

Victor Garcia Tascon public en insidecat.biz
Mie Sep 26 23:20:09 CEST 2012


Estimados compañeros del foro:

Llevo un par de años apuntado a "nuestra" lista,
leyendo y aprendiendo de vuestros mensajes.
Este es mi primer mensaje. Un saludo a todos.

Llevo unos cuantos meses probando CodeTyphon 2.70
bajo Windows XP SP3, todo 32 bits. En todos los .pas
pongo {$mode delphi} para evitarme problemas...

Las pruebas van bien, y empieza a gustarme Lazarus...

Pero me ha surgido un problema con unas rutinas, que
uso desde hace años en Delphi 6. Las rutinas los que
hacen es transformar (comprimir) numeros enteros, a 
strings de la mitad de su tamaño.

Un ejemplo:

el integer 9876543210 se convierte a 'ABCDE'

El codigo de las rutinas os lo pongo al final del mensaje.

El problema que me he encontrado al usarlas en Lazarus, es 
que en MUY POCAS ocasiones, devuelven una cadena con un char
menos de tamaño. Es decir, le paso 123456, me deberia dar algo
como XXX, pero me da solo XX.

Lo unico que se me ocurre, es que debido al uso de UTF-8 (o 
sabe dios que), alguna pareja de chars que devuelve la funcion,
se interprete como uno. Las funciones funcionan perfectamente en
Delphi 6, que creo que usa ANSI para los strings...

La verdad es que el rollo del utf-8 "para todo" en lazarus me
esta dando muchos problemas. Espero que las ventajas de usar 
utf-8 merezcan la pena.

Si a alguien se le ocurren ideas, las probare. Tambien podeis
comentar optimizaciones a las rutinas. Las uso a menudo en Delphi.

Estas son las funciones (que son open source para todos):

function TFPrincipal.EncodeTextInteger64(const num: int64):string;
// NECESITA: un numero entero positivo o negativo
// DEVUELVE: una cadena, de longitud par, con el numero codificado segun el siguiente esquema
//           - si el numero es negativo, se le quita el signo
//           - si el numero de cifras es impar, se añade un cero a la izquierda
//           - cada bloque de dos cifras, se sustituye por su código ASCII
//             desplazado 32 posiciones hacia adelante
//           - con el primero de ellos, distinguimos si es negativo o positivo:
//             si es positivo, se desplaza 32 como siempre (es decir, estara entre 32 y 131)
//             si es negativo, no estara desplazado 32, sino 32+100 (es decir, estara entre 132 y 

231)
// EJEMPLOS:   1056->   42   88 -> *X      90860599->122 118 37 131->zv%â
//            -1056-> 42+100 88 -> ÄX       -11231 ->133 44 63 ->à,?
// NOTAS: esta pensada para guardar numeros enteros grandes en ficheros de texto
//        se consigue un ahorro del 50% respecto a texto puro, y solo se pierde
//        un 25% respecto al formato binario (el mas eficiente)
var auxs, cacho: string;
    auxi: integer;
    neg: boolean;
begin
  result:='';
  neg:=false;
  if num>=0 then auxs:=inttostr(num)
  else begin auxs:=inttostr(-num); neg:=True; end;

  if length(auxs) mod 2 =1 then auxs:=' '+auxs;
  for auxi:=1 to length(auxs) do
  begin
    if (auxi mod 2)=0 then continue;
    cacho:=copy(auxs,auxi,2);
    result:=result+chr(strtoint(cacho)+32);
  end;
  if neg then result[1]:=chr(ord(result[1])+100);
end;


function TFPrincipal.DecodeTextInteger64(const numtext: string):int64;
// NECESITA: una cadena que sea un entero codificado segun EncodeTextInteger()
// DEVUELVE: el numero entero "decodificado", segun este esquema
//           - cada caracter, se pasa a numero ASCII u se le resta 32
//           - se compone el numero concatenado los ASCII
//           - en funcion del 1º sabemos si es negativo o no
// EJEMPLOS: *X->42 88->1056      zv%â->122 118 37 131->90860599
// NOTAS: es la complementaria de EncodeTextInteger()
var i: integer;
    auxs: string;
begin
  if numtext[1]>=#132 then auxs:='-'+format('%2.2d',[ord(numtext[1])-132])
  else auxs:=format('%2.2d',[ord(numtext[1])-32]);
  for i:=2 to length(numtext) do
    auxs:=auxs+format('%2.2d',[ord(numtext[i])-32]);
  result:=strtoint64(auxs);
end;

-- 
Saludos,
 Victor                          mailto:public en insidecat.biz





More information about the Lazarus-es mailing list