Ada ofrece tres clases de ristras de caracteres:
La librería "Ada.Strings" define elementos de carácter
general que se pueden usar con las distintas clases de ristras; entre
otros:
Space : constant Character := ' ';
type Alignment is (Left, Right, Center);
type Truncation is (Left, Right, Error);
type Membership is (Inside, Outside);
type Direction is (Forward, Backward);
type Trim_End is (Left, Right, Both);
El paquete estándar de Ada contiene la definición del
tipo String como un array
no restringido de caracteres con rango positivo:
type String is array(Positive range
<>) of Character;
Ello significa que, sin más, se pueden declarar ristras de
caracteres como versiones restringidas del tipo String:
S1, S2: String(1..10);
S3, S4: String(1..20);
Las variables de tipo String son arrays y se les puede aplicar
cualquier operación general de array, incluyendo la posibilidad
de acceder a los elementos individuales mediante un índice (los
elementos individuales son caracteres, no ristras):
C := S1(3); --C debe ser de tipo Character
S2(4) := 'a';
A una variable String se le puede asignar una ristra literal siempre
que tenga el tamaño adecuado:
S1 := "ABCDEFGHIJ";
S3 := "01234567890123456789";
Para asignar ristras de tamaños diferentes es necesario
incluir en la cláusula de
contexto las librerías "Ada.Strings" y "Ada.Strings.Fixed";
la
segunda ofrece un procedimiento llamado Move que permite esta
operación:
procedure Move (Source : in
String;
Target : out String;
Drop : in Truncation := Error;
Justify : in Alignment := Left;
Pad : in Character :=
Space );
El significado de los parámetros de Move es el siguiente: Source es la ristra a asignar, Target es la ristra donde se va a asignar, Drop indica qué hacer si Source tiene mayor longitud que Target (producir un error o cortar la ristra por uno de sus extremos, left, rigth, asignando sólo los caracteres que caben), Justify indica cómo alinear Source dentro de Target si tiene menor longitud y Pad es el carácter con que se rellenará el resto de Target, en ese caso.
Move(S1,S4);
--S4 =
"ABCDEFGHIJ "
Move(S1,S4,Pad =>'0');
--S4 = "ABCDEFGHIJ0000000000"
Move(S3,S2);
--¡ERROR!
Move(S3,S2,Drop => Left); --S2 = "0123456789"
Move(S1,S4,Justify => Right); --S4 = "
ABCDEFGHIJ"
Las ristras de tamaño fijo son las únicas a las que les son aplicables operaciones de entrada/salida , también se les pueden aplicar operadores relacionales; la concatenación de ristras se hace usando el operador "&" que en Ada está definido para cualquier array monodimensional.
S1 := "ABCDE" & "12345"; --S1="ABCDE12345"
Para la localización de una subristra dentro de una ristra se puede usar la función Index definida en la librería "Ada.Strings.Fixed" con el siguiente protocolo:
function Index (Source : in
String;
Pattern : in String;
Going : in Direction := Forward;
Mapping : in Maps.Character_Mapping
:= Maps.Identity)
return Natural;
Donde Source es la ristra donde se va a buscar, Pattern
es el patrón de búsqueda, Going es la
dirección de búsqueda (el tipo Direction está
definido en Ada.Strings con los valores Forward y Backward) y Mapping
especifica cómo se van a corresponder los caracteres.
S4 := "01234567890123456789";
I := Index(S4, "345"); --I = 4
J := Index(S4, "345", Backward); --J = 14
La extracción de una subristra se puede hacer
especificando un slice:
S2 := S4(3..12); --S2 = "2345678901"
S2(1..5) := "ABCDE"; --S2 = "ABCDE78901"
En las ristras de tamaño fijo se puede acceder a los caracteres individuales indicando su posición entre paréntesis:
S2 := "abcdefghij";
C := S2(5); -- C =
'e' (C es de tipo Character)
No confundir con:
S2 := "abcdefghij";
S := S2(5 .. 5); -- S = "e" (S es de tipo String(1
.. 1))
C := S2(5 .. 5)(5); -- Se obtiene el caracter a partir del Slice
Las ristras de tamaño limitado pueden tomar cualquier tamaño entre cero (ristra nula) y el número máximo de caracteres que se especifique en cada caso. La declaración de ristras de tamaño limitado requiere tres pasos:
Primero hay que incluir en la cláusula de contexto la librería genérica "Ada.Strings.Bounded".
with Ada.Strings.Bounded;
A continuación, dentro de la unidad de compilación,
hay que
instanciar la librería para los tamaños que se desee.
package Str10 is new
Ada.Strings.Bounded.Generic_Bounded_Length(10);
package Str20 is new
Ada.Strings.Bounded.Generic_Bounded_Length(20);
use Str10, Str20;
Sólo entonces se pueden declarar variables de tipo Bounded_String,
cualificado con la instancia que corresponda al tamaño deseado.
SL1, SL2: Str10.Bounded_String;
SL3, SL4: Str20.Bounded_String;
Se pueden asignar entre sí ristras de tamaño limitado
del
mismo tipo, pero no se puede asignar a una ristra de tamaño
limitado una de tamaño fijo (ni al revés) ni una ristra
literal (son de tamaño fijo), así como no se pueden
emplear en operaciones de entrada/salida. Afortunadamente, la
librería "Ada.Strings.Bounded" ofrece operaciones de
conversión entre ristras de tamaño fijo y ristras de
tamaño limitado.
function To_Bounded_String (Source : in
String;
Drop : in Truncation := Error)
return Bounded_String;
function To_String (Source : in Bounded_String)
return String;
El parámetro Drop es necesario cuando se convierte
una ristra de tamaño fijo a tamaño limitado porque la
primera podría tener un tamaño mayor que el límite
de la segunda y hay que especificar lo que se hace en ese caso; al
revés no es necesario: la función crea una ristra de
tamaño fijo exactamente igual a la longitud de Source.
get_line(S1,Lon);
SL1 := To_Bounded_String(S1(1..Lon));
put_line(To_String(SL1));
Recuerde que las funciones de conversión no cambian el tipo de la variable convertida (que es de entrada), sólo crean su valor equivalente en el nuevo tipo.
El valor Null_Bounded_String representa la ristra nula (equivale a To_Bounded_String("")).
SL1 := Str10.Null_Bounded_String;
SL2 := Str20.Null_Bounded_String;
Entre ristras de tamaño limitado son aplicables los
operadores relacionales;
la operación de concatenación se puede realizar tanto
usando
el operador "&" como la función Append:
function Append (Left, Right : in
Bounded_String;
Drop : in
Truncation := Error )
return Bounded_String;
La función Append devuelve la concatenación
de Left y Right; el parámetro Drop indica
qué hacer en caso de que el resultado tenga una longitud mayor
que el límite establecido.
SL1 := To_Bounded_String("Alfa"); --SL1 = "Alfa"
SL2 := To_Bounded_String("beto"); --SL2 = "beto"
SL1 := Append(SL1,SL2);
--SL1 = "Alfabeto"
SL2 := Append(SL1,SL2);
--¡ERROR!
SL2 := Append(SL1,SL2,Rigth); --SL2 =
"Alfabetobe"
Uno de los parámetros de Append puede
no ser de tipo Bounded_String (puede ser una ristra de
tamaño fijo, dinámico o un cáracter).
La longitud actual de una ristra de tamaño limitado
se obtiene con la función Length.
X := Length(SL1); --X = 8
La localización de una subristra requiere una
función Index similar a las de las ristras de
tamaño fijo.
function Index (Source : in Bounded_String;
Pattern : in String;
Going : in Direction := Forward;
Mapping : in Maps.Character_Mapping
:= Maps.Identity)
return Natural;
Para la operación de extracción la sintaxis de slices (que ya no se puede utilizar puesto que las ristras de tamaño limitado no son arrays) es sustituida por una función Slice.
function Slice (Source : in Bounded_String;
Low : in Positive;
High : in Natural)
return String;
La función Slice devuelve la subristra de Source
que empieza en la posición Low y acaba en la
posición High (ambas incluidas); el resultado es de
tamaño fijo.
SL3 := To_Bounded_String(Slice(SL1,3,6)); -- SL3 = "fabe"
En las ristras de tamaño limitado se puede acceder a los caracteres individuales usando una función llamada Element:
SL3 := To_Bounded_String("abcdefghij");
C := Element(SL3, 5);
-- C = 'e'
Las ristras de tamaño dinámico pueden tomar cualquier tamaño sin necesidad de una reserva previa. La declaración de ristras de tamaño dinámico requiere, en primer lugar, incluir en la cláusula de contexto la librería "Ada.Strings.Unbounded".
with Ada.Strings.Unbounded;
use Ada.Strings.Unbounded; --se puede incluir en el
use porque no es genérica
Entonces se pueden declarar variables de tipo Unbounded_String.
SD1, SD2, SD3, SD4: Unbounded_String;
Se pueden asignar entre sí ristras de tamaño
dinámico,
pero no se puede asignar a una ristra de tamaño dinámico
una de tamaño fijo o limitado (ni al revés) ni una ristra
literal (son de tamaño fijo), así como no se pueden
emplear
en operaciones de entrada/salida. Afortunadamente, la librería
"Ada.Strings.Unbounded" ofrece operaciones de conversión entre
ristras de tamaño fijo y ristras de tamaño
dinámico.
function To_Unbounded_String (Source : in
String)
return Unbounded_String;
function To_String (Source : in Unbounded_String)
return String;
La función To_Unbounded_String crea una ristra de
tamaño dinámico a partir de una de tamaño fijo y
la operación To_String hace lo contrario.
get_line(S1,Lon);
SD1 := To_UnBounded_String(S1(1..Lon));
put_line(To_String(SD1));
Recuerde que las funciones de conversión no
cambian el tipo de la variable convertida (que es de entrada),
sólo crean su valor equivalente en el nuevo tipo.
El valor Null_Unbounded_String representa la ristra nula (equivale a To_Unbounded_String("")).
SD1 := Null_Unbounded_String;
Entre ristras de tamaño dinámico son aplicables los
operadores relacionales; la operación de concatenación se
puede realizar tanto usando el operador "&" como el procedimiento
Append.
procedure Append (Source : in
out Unbounded_String;
New_Item : in Unbounded_String);
El procedimiento Append crea una ristra concatendo Source
con New_item y pone el resultado en Source (que
queda modificada).
SD1 := To_Unbounded_String("Alfa"); --SD1 = "Alfa"
SD2 := To_Unbounded_String("beto"); --SD2 = "beto"
Append(SD1,SD2);
--SD1 = "Alfabeto"
El segundo parámetro de Append puede
no ser de tipo Unbounded_String (puede ser una ristra de
tamaño
fijo, dinámico o un cáracter).
La longitud actual de una ristra de tamaño dinámico se obtiene con la función Length.
X := Length(SD1); --X = 8
La localización de una subristra requiere una
función Index similar a las de las ristras de
tamaño fijo.
function Index(Source : in
Unbounded_String;
Pattern : in String;
Going : in Direction := Forward;
Mapping : in Maps.Character_Mapping
:= Maps.Identity)
return Natural;
Para la operación de extracción la sintaxis de slices (que ya no se puede utilizar puesto que las ristras de tamaño limitado no son arrays) es sustituida por una función Slice.
function Slice (Source : in UnBounded_String;
Low : in Positive;
High : in Natural)
return String;
La función Slice devuelve la subristra de Source
que empieza en la posición Low y acaba en la
posición High (ambas incluidas); el resultado es de
tamaño fijo.
SD3 := To_Unbounded_String(Slice(SD1,3,6)); -- SD3 = "fabe"
En las ristras de tamaño dinámico se puede acceder a los caracteres individuales usando una función llamada Element:
SD3 := To_Unbounded_String("abcdefghij");
C := Element(SD3, 5);
-- C = 'e'
© Grupo de Estructuras de Datos y Lingüística Computacional - ULPGC.
Anterior | Superior | Siguiente