Programación en Ada/Unidades predefinidas/Ada.Text IO

De Wikilibros, la colección de libros de texto de contenido libre.

Ada.Text_IO es un paquete predefinido para la entrada y salida de texto.

Tiene procedimientos Get y Put para strings y caracteres; y varios paquetes genéricos anidados para la entrada/salida de otros tipos en formato texto: Decimal_IO, Enumeration_IO, Fixed_IO, Float_IO, Integer_IO y Modular_IO.

Ejemplo de E/S por consola[editar]

with Ada.Text_IO;
with Ada.Characters.Handling;

-- Lee de entrada un número entero no dejando al usuario escribir
-- caracteres que no sean dígitos. Esta versión sólo funciona
-- correctamente en Windows. Para que funcione en Linux y otros
-- sistemas Unix, hay que cambiar los valores de Intro y Back.

procedure Leer_Entero is

   -- Para Linux cambiar por ASCII.LF
   Intro : constant Character := ASCII.CR;
   -- Para Linux cambiar por ASCII.Del
   Back : constant Character := ASCII.BS;
   
   Char : Character;
   Fin : Boolean := False;
   Número : Natural := 0;

   -- Cadena para leer el número carácter a carácter
   -- El máximo de caracteres es Integer'Width - 1 porque no leemos signo
   Cadena_Número : String (1 .. Integer'Width - 1);

begin
  Ada.Text_IO.Put ("Escriba un número y pulse Enter: ");

  while not Fin loop

      Ada.Text_IO.Get_Immediate (Char);
     
      if Ada.Characters.Handling.Is_Digit (Char) then
          Número := Número + 1;
          Cadena_número(Número) := Char;
          Ada.Text_IO.Put (Char);
      elsif Char = Intro then
          Fin := True;
      elsif Número>0 and Char = Back then
          -- Si el usuario ha pulsado la tecla backspace
          -- borra el dígito escrito anteriormente
          Ada.Text_IO.Put (ASCII.BS & ' ' & ASCII.BS);
          Número:=Número-1;
      end if;

  end loop;

  Número := Integer'Value (Cadena_Número (1 .. Número));
  Ada.Text_IO.New_line;
  Ada.Text_IO.Put_Line ("Has escrito:" & Integer'Image (Número));
exception
   when Constraint_Error =>
      Ada.Text_IO.New_line;
      Ada.Text_IO.Put_Line ("Lo siento: " & Cadena_Número &
                            " es demasiado largo para almacenarse");
end Leer_Entero;

Ficheros de texto[editar]

Ada.Text_IO también permite el acceso y modificación de ficheros de texto de forma secuencial.

La mayoría de funciones de Ada.Text_IO están disponibles para ser usadas con ficheros de texto. Para eso, se usan variables de tipo File_type, necesarias para especificar a qué archivo acceder. Muchas de las funciones conocidas para consola de Ada.Text_IO se pueden usar en archivos de texto pasando por parámetro una variable de tipo File_type.

Algunas funciones y procedimientos para el manejo de ficheros con Ada.Text_IO:

Open(F,Modo,Ruta)
Permite abrir un fichero. Si el fichero no existe, devuelve una excepción 'Name_error'. 'F' es una variable File_type, 'Ruta' es la ruta del sistema donde se localiza el fichero y 'Modo' especifica como abrir el fichero: 'In_file' significa lectura, 'Out_file' significa escritura (borrando lo anterior) y 'Append_file' significa escritura empezando desde el final. Para acceder a este archivo, lo haremos a través de la variable File_type 'F'.
Create(F,Modo,Ruta)
Crea un fichero en la ruta del sistema elegida. Si no existe, se crea, y si existe, se sobreescribe. Los parámetros son los mismos que en 'Open', pero por defecto el modo es 'Out_file' (si creas un archivo, suele ser para escribir en él). Para acceder a este archivo, lo haremos a través de la variable File_type 'F'.
Close(F)
Cierra el archivo referido por la variable 'F'. Es necesario hacer esto cuando dejemos de leer o escribir en un fichero.
Get(F,C)
Lee un carácter de un fichero, siendo F una variable File_type y 'C' una variable character. Para leer se debe haber hecho un 'Open' previamente.
Put(F,C)
Escribe un carácter en un fichero, siendo F una variable File_type y 'C' una variable Character. Para escribir se debe haber hecho un 'Open' en modo escritura o un 'Create' previamente.
End_of_file(F)
Esta función devuelve 'True' (boolean) si hemos llegado al final del fichero y 'False' si quedan elementos por leer. Es importante saber usar esta función, ya que si intentamos leer un elemento del fichero habiendo llegado al final de éste, saltará la excepción 'End_Error'.
End_of_line(F)
Esta función devuelve 'True' (boolean) si hemos llegado al final de la linea actual y 'False' si quedan elementos por leer.
Reset(F)
Reinicia el cursor; para saber que elemento estamos leyendo, se guarda un cursor con la posición del elemento actual; esta operación lo reinicia, como si cerrásemos el fichero y lo volviésemos a abrir.

Para encontrar la lista completa de operaciones sobre ficheros de Ada.Text_IO, se puede ver en el manual de referencia: A.10.1 Text_IO.

Ejemplo de E/S por fichero[editar]

 with Ada.Command_Line,Ada.Text_Io;
 use Ada.Command_Line,Ada.Text_Io;

 procedure Visor_texto is 
 
  -- Lee de un fichero de texto cuya ruta se pasa por parámetro o se pregunta
  -- explícitamente, y se visualiza por pantalla, tomando como 'estándar' una consola
  -- de 24 líneas de largo y 80 caracteres de ancho
 
   Caracteres_Por_Linea : constant Natural                            := 79;  
   Lineas_Por_Pantalla  : constant Natural                            := 24;  
   F                    :          File_Type;  
   Linea                :          String (1 .. Caracteres_Por_Linea);  
   Indice               :          Natural;  
   Contador             :          Natural                            := 0;  
   
    procedure Esperar_Tecla  is 
      C : Character;  
   begin 
      Get_Immediate(C);
   end Esperar_Tecla;
   
begin 
  if Argument_Count>0 then 
  -- Si hay parametros, usamos el primero como ruta del archivo
     Open(F,In_File,Argument(1));
  else 
  -- Si no hay parámetros, preguntamos explícitamente la ruta del archivo
     Put_Line("Introduzca la ruta del archivo a abrir: ");
     Get_Line(Linea,Indice);
     Open(F,In_File,Linea(1..Indice));
     New_Line(3);
  end if;

  Put_Line("-----------------------------------");
  Put_Line("- Visor de texto - " & Name(F)); 
  Put_Line("-----------------------------------");
  -- La función Name() nos devuelve la ruta del archivo
  New_Line(2);

  while not End_Of_File(F) loop     -- Leemos hasta llegar al final del fichero
     -- Si llegamos al final e intentamos leer, dará error, por lo que hay que prevenirlo
     if Contador>=Lineas_Por_Pantalla-2 then 
        New_Line;
        Put_Line("---- Presione una tecla para continuar");
        Esperar_Tecla;
        New_Line;
        Contador:=0;
     end if ;
     -- Leemos una linea desde el archivo, tomando su longitud en 'Indice' 
     -- y guardando la linea en un string
     Get_Line(F,Linea,Indice);
     -- Visualizamos la linea obtenida por pantalla, pero solo hasta la longitud obtenida
     Put_Line(Linea(1..Indice));
     Contador:=Contador+1;
  end loop ;
  Close(F);

-- Controlamos posibles errores que puede haber con ficheros
exception 
  when Name_Error=>
     New_line(2);
     Put_Line("**** Error ****");
     Put_Line("Nombre de archivo no valido");
  when Use_Error=>
     New_line(2);
     Put_Line("**** Error ****");
     Put_Line("Archivo ya abierto o inaccesible");
end Visor_texto;

Portabilidad[editar]

Un programa hecho en Ada usando la librería Ada.Text_IO debería poderse compilar sin problemas (si no se usan librerías propias del sistema) tanto en sistemas Windows como en sistemas Unix (incluyendo GNU/Linux) . Sin embargo, puede que su funcionamiento no sea igual en ambos sistemas si no se tienen en cuenta ciertas diferencias en sus consolas.

Por ejemplo, todos los sistemas Unix soportan el estándar de terminal ANSI, mientras que en Windows ME, NT, 2000 y XP la consola no es compatible con ANSI (aunque es posible configurarlo cargando el driver ANSI.SYS). Además el salto de linea es diferente en Unix y en Windows: en sistemas Unix consta de un carácter y en Windows de dos. A la hora de programar, has de tener en cuentas algunas diferencias:

  • El salto de línea en sistemas Unix es ASCII.LF. En Windows es ASCII.LF & ASCII.CR. Sin embargo usando Get_Line, End_Of_Line y Put_Line se asegura portabilidad en este aspecto.
  • Algunas funciones de Ada.Text_IO no funcionan correctamente en Windows, como el procedimiento New_Page. Get_immediate(C,B) también puede dar problemas con algunas teclas en Linux.
  • El carácter de control asociado a ciertas teclas puede variar entre Unix y Windows. Por tanto si tu programa intenta detectar pulsaciones de teclas específicas, como 'Enter', etc. deberás adecuar el carácter con el que se identifica la tecla. Algunos ejemplos:
Intro: character:=ASCII.Cr;  -- Windows
Intro: character:=ASCII.Lf;  -- Unix
Backspace: character:=ASCII.Bs;   -- Windows (tecla de borrar)
Backspace: character:=ASCII.Del;  -- Unix

Debes tener esto en cuenta si deseas hacer portable tu programa, y que funcione tanto en Unix como en Windows. Por lo tanto recomendamos que pruebes la aplicación en ambos sistemas si es posible, para asegurar su buen funcionamiento. Si deseas más funciones para la consola, y ver sus diferentes implementaciones en Linux y Windows, puedes mirar el paquete Pantalla_ansi.

Manual de referencia de Ada[editar]