|
Determinando la longitud real de una cadena
Copyright © 2000 Ernesto
De Spirito
Introducción
La función Length nos devuelve la longitud de una cadena,
pero se comporta de modo diferente según el tipo de cadena. Para
las viejas cadenas cortas (ShortString) y para las cadenas
largas (AnsiString), Length devuelve la cantidad
de bytes que tiene una cadena, mientras que para las
cadenas anchas (WideString) devuelve la cantidad de
caracteres anchos (WideChar), es decir la cantidad
de bytes dividido dos.
En el caso de las cadenas cortas y largas, en los idiomas
occidentales un caracter ocupa un byte, mientras que por ejemplo
en idiomas asiáticos algunos caracteres ocupan un byte y otros
dos. Es por esta razón que existen dos versiones de casi todas
las funciones de cadena, una de gran rendimiento que sólo sirve
para cadenas con caracteres de un sólo byte (SBCS) y otra de menor
rendimiento que sirve también para cadenas de caracteres de uno o dos
bytes (DBCS) y que se usan principalmente por quienes pretenden distribuir
aplicaciones internacionalmente. Así es que por ejemplo tenemos funciones
como Pos, LowerCase y UpperCase por un
lado y AnsiPos, AnsiLowerCase y AnsiUpperCase por
otro. Curiosamente no hay una función AnsiLength que nos
devuelva la cantidad de caracteres de una cadena DBCS.
AnsiLength (Borrador)
Aquí va entonces una función que devuelve la cantidad de caracteres
de una cadena de dos bytes:
uses SysUtils;
function AnsiLength(const s: string): integer;
var
i, n: integer;
begin
Result := 0;
n := Length(s);
i := 1;
while i <= n do begin
inc(Result);
if s[i] in LeadBytes then inc(i);
inc(i);
end;
end;
AnsiLength (Final)
Naturalmente, esta función no está optimizada. No vamos a
meternos con lenguaje ensamblador, pero por lo menos podemos
usar punteros:
uses SysUtils;
function AnsiLength(const s: string): integer;
var
p, q: pchar;
begin
Result := 0;
p := PChar(s);
q := p + Length(s);
while p < q do begin
inc(Result);
if p^ in LeadBytes then
inc(p, 2)
else
inc(p);
end;
end;
|