Resolución de Problemas y Algoritmos – Segundo cuatrimestre 2015 Clase 10: Archivos de texto (text) Dr. Sergio A. Gómez http://cs.uns.edu.ar/~sag Departamento de Ciencias e Ingeniería de la Computación Universidad Nacional del Sur Bahía Blanca, Argentina Motivaciones • Quisiera leer cadenas de caracteres de un archivo generado por el bloc de notas tal que contuviera números enteros y recuperar uno a uno los enteros (pensar cómo se hace con file of char). • Quisiera leer de un archivo del bloc de notas los datos de la misma manera que lo hago cuando proceso los datos del buffer • Quisiera procesar los fin de línea de un archivo del bloc de notas en forma independiente del sistema (¿por qué?) Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 2 Archivos de texto en Pascal (TEXT) • En Pascal, existe un TIPO PREDEFINIDO TEXT para archivos de texto, esto es, una sucesión finita de componentes de tipo CHAR que pueden accederse una a una, comenzando de la primera. Program Ejemplo; TYPE TArchivoTexto = text; VAR T1, T2 : TArchivoTexto; documento : text; 3 Problema: Escriba un programa para abrir un archivo de texto ya existente llamado “texto.txt”, y mostrar por pantalla su contenido. program Leer; var T : text; elemento: char; begin Assign( T, ‘texto.txt’ ); Reset(T); {abre el archivo para leer de él} while not Eof(T) do begin Read(T,elemento); Write(elemento); end; Close(T); end. 4 Problema: Leer el texto de un archivo de texto c:\texto.txt por teclado y grabarlo en el mismo. program LeerYGenerar; var c : char; f : text; begin WriteLn( 'Ingrese un texto terminado en punto' ); Assign( f, 'c:\texto.txt' ); { vinculo f con c:\texto.txt } Rewrite( f ); { creo archivo f } Read( c ); { leo c del teclado } while c <> '.' do begin Write( f, c ); { grabo c en el archivo f } Read( c ); { leo c del teclado } end; Close( f ); { cierro archivo } end. Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 5 Operaciones sobre archivos de texto en Pascal • Además de las operaciones vistas sobre archivos secuenciales se agregan: Procedimientos predefinidos: • readln(T): desplaza el “puntero” de lectura en T hasta el carácter siguiente a un fin de línea (enter). • writeln(T): escribe un fin de línea (enter) en T. Función predefinida: • eoln(F) (end of line): retorna TRUE si se llegó al final de una línea y FALSE en caso contrario. Observaciones: readln(T,e) es equivalente a read(T,e); readln(T) writeln(T,e) es equivalente a write(T,e); writeln(T) Resolución de Problemas y Algoritmos Dr. Alejandro J. García 6 End Of Line (fin de línea) EOL • End-of-line (EOL) fin de línea (o line break o newline) es un caracter especial, o secuencia de caracteres, que indica el final de una línea de texto y el paso a la siguiente. • Se le llama así porque el carácter a la derecha de EOL aparecerá en la línea de abajo. • Los sistemas operativos representan EOL con uno o dos códigos de control: LF (Salto de línea) o CR (Retorno de carro) o ambos. Por ejemplo: – LF: Multics, Unix, GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD , BeOS, Amiga, RISC OS, – CR+LF: MS-DOS, OS/2, Microsoft Windows, Symbian – CR: Commodore 8-bit, TRS-80, Apple II family, Mac OS 7 ¿Recuerda esto? • En las máquinas de escribir mecánicas al finalizar un renglón hay que hacer dos movimientos: (1) retorno de carro (2) nueva línea • La tecla ENTER tiene asociados 2 caracteres: (1) ASCII 13: retorno de carro (CR: carriage return) (2) ASCII 10: nueva línea (LF: line feed) • Los caracteres 13 y 10 son caracteres de control y al imprimirlos en pantalla producen un efecto en lugar de mostrar algo visible. Vea por ejemplo: Program uno; Begin WRITE(CHR(65)); WRITE(CHR(66)); End . Program dos; Begin WRITE(CHR(65)); WRITE(CHR(13)); WRITE(CHR(10)); WRITE(CHR(66)); End . Program tres; Begin WRITE(CHR(65)); WRITE(CHR(10)); WRITE(CHR(66)); End . 8 Problema: escriba un programa para abrir un archivo de texto ya existente llamado “texto.txt”, y contar cuántas líneas tiene. Program Lineas; var T : text; cant : integer; begin Assign( T, ‘texto.txt’ ); Reset( T ); cant := 0; while not Eof(T) do begin ReadLn( T ); cant := cant + 1; end; WriteLn(‘Cantidad de líneas: ’, cant); Close( T ); end. 9 Problema: Escriba un programa para abrir un archivo de texto ya existente llamado “texto.txt”, y generar otro llamado “otro.txt” que cuando se encuentre un punto en “texto.txt” se grabe un enter en “otro”. Program AgregarEnterDetrasDePuntos; VAR T1, T2: Text; c : char; Begin Assign( T1, ‘texto.txt’ ); Reset( T1 ); Assign( T2, ‘otro.txt’ ); Rewrite( T2 ); while not Eof( T1 ) do begin Read( T1, c ); Write( T2, c ); if c = ‘.’ then WriteLn( T2 ); end; Close( T1 ); close( T2 ); end. 10 Problema propuesto • Problema: Dado un archivo de texto conteniendo un programa Pascal se desean eliminar todos los comentarios de la forma { …. }. Para ello se debe generar otro archivo de texto con el contenido del archivo original pero sin los comentarios. • Algoritmo: Leer uno por uno los caracteres del archivo: Cada vez que aparece un carácter “{“, anotaremos que estamos dentro de un comentario y no grabaremos el los caracteres leídos. Cuando aparece el carácter “}”, anotamos que estamos fuera de un comentario y empezamos a grabar los caracteres leídos. 11 program SacarComentarios; const Origen = 'c:\programa.pas'; Destino = 'c:\sincomentarios.pas'; type TEstado = ( dentro, fuera ); var ori, dst : text; c : char; estado : TEstado; begin Assign( ori, Origen ); Assign ( dst, Destino ); Reset( ori ); Rewrite( dst ); estado := fuera; while not Eof( ori ) do begin Read( ori, c ); if (c='{') or (c='}') then case c of '{' : if estado = fuera then estado := dentro; '}' : estado := fuera; end else if estado = fuera then write( dst, c ); end; Close( ori ); Close( dst ); Resolución de Problemas y Algoritmos - Dr. 12 end. Sergio A. Gómez Problema: Dado un archivo de texto llamado c:\archivo.txt, generar otro archivo de texto llamado c:\resumen.txt, donde cada párrafo es separado por una línea del siguiente, y se muestra la cantidad de caracteres del párrafo como información de resumen. Algoritmo: Abro archivo y creo un resumen vacío. Creo un contador de caracteres y cada vez que aparece un carácter lo cuento. Cuando termina un párrafo (aparece un enter), imprimo la información de resumen y reseteo el contador de caracteres. Finalmente, cierro los archivos. Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 13 program ResumenArchivo; const NombreArchivo = 'c:\archivo.txt'; NombreResumen = 'c:\resumen.txt'; var arch, resumen : text; c : char; cont : integer; begin Assign( arch, NombreArchivo ); Assign( resumen, NombreResumen ); Reset( arch ); { Abro archivo para sólo lectura. } Rewrite( resumen ); { Abro resumen para sólo escritura. } Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 14 cont := 0; { Inicialmente no conté caracteres. } while not Eof( arch ) do begin if Eoln( arch ) then begin { Encontre Enter, lo consumo e imprimo resumen. } ReadLn( arch ); WriteLn( resumen ); WriteLn( resumen, 'Cantidad de caracteres: ', cont ); cont := 0; WriteLn( resumen, '---------------------------------' ); end else begin { No hay enter, consumo carácter y lo cuento. } Read( arch, c ); Write( resumen, c ); cont := cont + 1; end; end; Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 15 { Si el archivo no termina con enter, } { muestro el último resumen. } if cont <> 0 then begin WriteLn( resumen ); WriteLn( resumen, 'Cantidad de caracteres: ', cont ); WriteLn( resumen, '---------------------------------' ); end; { Cierro los archivos. } Close( arch ); Close( resumen ); end. Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 16 Secuencias de números en archivos de texto •A pesar de que los archivos de texto contienen caracteres, es posible interpretar su representación alfanumérica en el archivo y hacer que Pascal la traduzca a la representación de un tipo primitivo de la misma manera que se interpretan los datos leídos de teclado. •Problema: Encontrar el máximo de una secuencia de números enteros no negativos leídos de un archivo de texto llamado c:\numeros.txt. Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 17 program MaximoDeNumeros; var f : text; n, max : integer; begin Assign( f, 'c:\numeros.txt' ); Reset( f ); max := -1; while not Eof(f) do begin Read( f, n ); if n > max then max := n; end; Close( f ); WriteLn( 'El maximo del archivo es: ', max ); WriteLn( 'Enter...' ); ReadLn; end. Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 18 Datos heterogéneos en archivos text •A pesar de que los archivos de texto contienen caracteres, es posible interpretar su representación alfanumérica en el archivo y hacer que Pascal la traduzca a la representación de un tipo primitivo de la misma manera que se interpretan los datos leídos de teclado. •Esta técnica requiere mucha atención por parte del programador ya que puede inducir a cometer errores muy fácilmente (ej: leer un dato cuyo tipo es incorrecto). •Problema: Dado un archivo de texto que contiene el texto de dos enteros y tres números reales separados por blancos, hallarResolución el mínimo los- Dr.5. de Problemas yde Algoritmos 19 Sergio A. Gómez program HallarMinimoDeCinco; const NombreArchivo = 'c:\archivo5.txt'; var T : text; i, j : integer; x, y, z : real; minimo : real; begin Assign( T, NombreArchivo ); Reset( T ); Read( T, i, j, x, y, z ); Close( T ); minimo := i; { En las próximas clases veremos cómo escribir } { esto en forma más elegante…} if j < minimo then minimo := j; if x < minimo then minimo := x; if y < minimo then minimo := y; if z < minimo then minimo := z; WriteLn( 'El minimo es: ', minimo : 10 : 4 ); end. Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 20 Appending • La operación Append( A ) permite abrir un archivo de texto para grabar datos al final de su contenido actual. El archivo debe existir sino se produce un error en ejecución. • Problema: Leer una cadena terminada en punto y hacer un appending en el archivo c:\texto.txt. Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 21 program AgregarAlFinal; var a : text; c : char; Begin WriteLn( ‘Ingrese una cadena terminada en punto:’ ); Assign( a, 'c:\texto.txt' ); Append( a ); repeat Read( c ); Write( a, c ); until c='.'; Close( a ); end. Resolución de Problemas y Algoritmos - Dr. Sergio A. Gómez 22 Problemas simples para practicar con TEXT • Problema: Escriba un programa que determine cuántas veces está el carácter E (ingresado por el usuario) en un archivo de texto. • Problema: Escriba un programa que determine cuántas veces está el carácter E (ingresado por el usuario) en cada línea de un archivo de texto. • Problema: Escriba un programa que agregue dos líneas en blanco al principio de un archivo de texto. • Problema: Escriba un programa reemplace el carácter E por otro C (ingresados por el usuario) en un archivo de texto. 23