Archivos
Archivos de texto
Implementá una función que lea una línea (cadena de caracteres) de largo indefinido (de cualquier
FILE *
) y la retorne por el nombre. Implementar otra función que realice lo mismo, pero retornando la cadena leída por la interfaz y si todo salió bien por el nombre. Prototipos:char * readline(FILE *); bool readline(FILE *, char **);
La función se puede implementar tanto con
fgetc()
como confgets()
. Hacerlo de ambas maneras.Escriba un programa que guarde todo lo que el usuario escriba mientras no escriba una cadena centinela pasada como argumento:
$ ./editor texto.txt "hasta la victoria" *** Guardaré todo lo que escribas en el archivo: texto.txt *** *** Para terminar, el centinela es: hasta la victoria *** Ayer te vi que subías por el camino a la fuente dime dónde vas, morena dime dónde vas, salada. hasta la victoria *** Hasta acá llegamos ***
Escriba un programa que copie un archivo de texto. Utilice argumentos en línea de comandos para indicar el archivo de entrada y el archivo de salida.
Escriba un programa que lea un archivo de texto y lo imprima, agregando en número de línea al comienzo:
$ ./numerar texto.txt 1: Ayer te vi que subías 2: por el camino a la fuente 3: dime dónde vas, morena 4: dime dónde vas, salada.
Opcional: agregue un argumento al programa para indicar en qué número debe comenzar a imprimir. Interpretación libre.
Escriba un programa que cuente la cantidad de líneas de un archivo, si el programa recibe el argumento
-l
. Opcionalmente, agregue al programa la posibilidad de contar palabras si recibe el argumento-w
y bytes si recibe el argumento-c
. Si recibe más de un archivo como argumento, imprime los totales, como se muestra a continuación:$ ./mi_wc -l texto.txt 4 texto.txt $ ./mi_wc -c texto.txt 98 texto.txt $ ./mi_wc -w texto.txt 19 texto.txt $ ./mi_wc -l -c -w texto.txt 4 19 98 texto.txt $ ./mi_wc -c -w -l texto.txt 4 19 98 texto.txt $ ./mi_wc -w -l -c texto.txt completa.txt 4 19 98 texto.txt 16 78 404 completa.txt 20 97 502 total
Escriba un programa que lea uno o varios archivos de texto e imprima únicamente las líneas del mismo que contengan una determinada palabra pasada como primer argumento al programa:
$ ./mi_grep morena texto.txt dime dónde vas, morena $ ./mi_grep morena texto.txt completa.txt texto.txt:dime dónde vas, morena completa.txt:dime dónde vas, morena completa.txt:Dime dónde vas, morena completa.txt:dime dónde vas, morena $ ./mi_grep modelo texto.txt completa.txt completa.txt:Voy a la cárcel modelo
Opcional: permita que programa reciba un argumento,
-n
, que indique que se desea imprimir el número de línea correspondiente.$ ./mi_grep -n morena texto.txt completa.txt texto.txt:3:dime dónde vas, morena completa.txt:3:dime dónde vas, morena completa.txt:9:Dime dónde vas, morena completa.txt:11:dime dónde vas, morena
Escriba un programa que reciba 2 cadenas,
nueva
yvieja
, y reemplace todas las ocurrencias devieja
pornueva
, en los archivos pasados como argumento.$ ./mi_sed "vieja frase" "somos progre" archivo.txt archivo.tex
Archivos binarios
Escribí un programa que genere un archivo binario grabando en él los números enteros del 0 al 1000000.
Escribí un programa que cargue un vector de enteros con los números almacenados en el archivo generado en el punto anterior.
Escribí el programa asumiendo que conocés la cantidad de números a leer.
Escribí el programa asumiendo que no conocés la cantidad de números a leer.
Dada la definición de la estructura
materia_t
como se muestra a continuaciónstruct materia { unsigned char codigo_departamento; unsigned char codigo_materia; char nombre[100]; }; typedef struct materia materia_t;
Cargar un vector de materias y:
Guardá ese vector en un archivo binario; después levantalo a un vector dinámico y ordenalo por departamento.
Repetí el proceso cargando el archivo en un vector de punteros a estructuras.
Con el vector del punto anterior, guardá en un nuevo archivo sólo las materias de un determinado departamento.
Dada las siguientes definiciones para una persona
struct direccion { char provincia[56]; char ciudad[20]; char calle[30]; int numero; char unidad[7]; char cpa[10]; }; /* definí el enum genero según tu preferecia */ typedef enum genero genero_t; struct persona { char * nombre; char * apellido; genero_t genero; int edad; struct direccion * direccion; }; typedef struct persona persona_t;
Escribí un programa que cargue un vector de punteros a estructuras de tipo
persona_t
. Para hacerlo, seguí una de las siguientes estrategias:generá un número aleatorio entero entre 1 y 3 y cargá esa cantidad, luego generá otro número aleatorio entre 0 y 1.0, si es mayor a 0.1, repetí el proceso. Hacelo hasta que el número aleatorio sea menor a 0.1. Las estructuras son generadas con datos aleatorios (seguramente sin sentido).
pedile todos los datos a la persona que ejecute el programa, para que ingrese una a una las personas de la lista. El ingreso finaliza cuando se ingresa un centinela.
Con el vector de estructuras cargado, guardalas en un archivo binario recibido como parámetro del programa. Considerá que el archivo ya puede tener otros datos.
Escribí un programa que cargue los datos almacenados en un archivo binario como el generado en el inciso anterior e imprima por pantalla únicamente aquellas personas que cumplan:
su edad cumple con algún criterio pasado como argumento,
su género cumple con algún criterio pasado como argumento,
su país cumple con algún criterio pasado como argumento.
Pueden ser 3 programas distintos. ¿Cómo lo invocarías?
Aplicación
En Construcción
En este ejercicio y en este otro ejercicio procesamos líneas con campos de ancho fijo. Siguiendo esa línea, vamos (vas) a escribir un programa que procese un archivo con campos de ancho fijo. Para ello, vamos a suponer que lo que tenemos que mantener es un software de transacciones bancarias.
Un archivo,
transacciones.log
, contiene líneas con campos de ancho fijo. Cada línea contiene 22 dígitos que corresponden a un CBU [1] de origen, luego 22 dígitos que corresponden al CBU destino, y luego 10 dígitos que corresponden al monto transferido en centavos. Sin embargo, se ha decidido que para evitar transacciones fraudulentas, el monto máximo a transferir sea 42949672.95 y no puede ser negativo ni cero. Un ejemplo de una línea válida es:285059094009041813520128505909400904181352020000052395
Un CBU está compuesto por 3 dígitos que corresponden a la entidad bancaria, 4 dígitos que corresponden a la sucursal, 1 dígito verificador (que ignoraremos), 13 dígitos del número de cuenta y 1 dígito verificador de cuenta (que ignoraremos). Como se muestra en la imagen siguiente, tomada de wikipedia.
Otro archivo,
cuentas.dat
, contiene estructuras que representan una cuenta bancaria, según la estructuracuenta_t
más abajo.typedef struct { int entidad; int sucursal; long int cuenta; } cbu_t; typedef struct { char provincia[STR_PROVINCIA_MAX]; char ciudad[STR_CIUDAD_MAX]; char calle[STR_CALLE_MAX]; int numero; char unidad[STR_UNIDAD_MAX]; char cpa[STR_CPA_MAX]; } direccion_t; typedef struct { cbu_t cbu; long int saldo; direccion_t direccion; char nombre[STR_NOMBRE_MAX]; } cuenta_t; typedef struct { cbu_t cbu_origen; cbu_t cbu_destino; long int monto; } transaccion_t;
Escriba un programa que lea el archivo
transacciones.log
y actualice los registros almacenados encuentas.dat
.¿Qué ocurre si en lugar de utilizar los CBUs se utilizan los índices del registro dentro del archivo para almacenar las transacciones?. Por ejemplo, un archivo puede tener 100 registros, y una transacción almacenada como:
0210520000052395
representa una transacción de 523.95 pesos de la cuenta 21 a la cuenta 52.
En este ejercicio y este otro ejercicio procesamos líneas con campos separados por delimitadores (comas en particular).
http://www.gpsinformation.org/dale/nmea.htm
$GPGGA,092750.000,5321.6802,N,00630.3372,W,1,8,1.03,61.7,M,55.2,M,,*76 $GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A $GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70 $GPGSV,3,2,11,02,39,223,19,13,28,070,17,26,23,252,,04,14,186,14*79 $GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76 $GPRMC,092750.000,A,5321.6802,N,00630.3372,W,0.02,31.66,280511,,,A*43 $GPGGA,092751.000,5321.6802,N,00630.3371,W,1,8,1.03,61.7,M,55.3,M,,*75 $GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A $GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70 $GPGSV,3,2,11,02,39,223,16,13,28,070,17,26,23,252,,04,14,186,15*77 $GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76 $GPRMC,092751.000,A,5321.6802,N,00630.3371,W,0.06,31.66,280511,,,A*45
typedef struct nmea_time { int year; int mon; int day; int hour; int min; int sec; int hsec; } nmea_time; typedef struct nmea_gga { nmea_time utc; double lat; double lon; int fix_quality; int satellites; double HDOP; double elv; double diff; double dgps_age; int dgps_sid; } nmea_gga;