P q p m a d n en C (Tutoriai)(comimwi6n) m.m.Eric Jeltsch F. PUNTEROS Y ESTRUCTURAS El pasar y retornar datos esíructurados a funciones puede ser no tan eficiente, ~articmh-mentesi la estructura es muy grande. Podemos eliminar el excesivo movimiento de datos utilizando punteros a la estructura, accediendo indirectamentea 10s datos a travds de punteros. Una modificación del problema anterior, versión puntero. /* Este programa lee e imprime datos de una partida de un inventano */ #include<stdio.h> stnict inventario{ int partida-no; float costos; float precio; 1; void leergartida(struct inventario *partptr); void printqartida(struct inventario *partptr); main() { stmct inventario item; printqn***Partida Datos de Inventario***bh"); leerqartida(&item); printgartida(&item); r-(O); 1 /* Imprime datos para una partida apuntada por partptr*/ void printqartida(struct inventario *partptr) { printf("Partida N"= %d, Costos=O!5.2f, Precios=O!5.2h", (*par&). costos, (*partptr).precio); (*partptr).partida-no, 1 /* lee datos para una partida en un objeto apuntado por partptr*l void leerqartida(struct inventario *partptr) { int n; float x; stmct inventario partida; printqMPartidaN": "); scanf("%dW,&n); (*partpir).partida-n~n;/* es equivalente a partptr->partida-no*/ printq"Costos: "); scanf("%f", &x); (*partptr).costos=x;/* es equivalente a partptr -> costos*/ pnntf("Preci0: "); scanf("%f ', &x); (*partptr).preci-;/* es equivalente a partptr -> precio*/ )/* genera la misma salida*/ Universidad de La Serena Area de Computaci6n &f. Dr. Eric Jeltsch F. Consideremos ahora un ejemplo usando estructuras anidadas #include<stdio.h> #define FAZ. O #define VER 1 súuct nombre_re{ char apellido[l 51; char nombre1[1S]; char nombre2[15]; struct &-re{ char calle[25]; char ciudad[l S]; struct rotulo { stxuct nombre-re nombre; stxuct direc-re direccion; void print-rotulo(struct rotulo *personaptr); int leer-rotulo (stnict rotulo *personaptr); main() { struct rotulo persona; printf("* **Datos Rotulados para una Persona***huiM); leer-rotulo(&persona); printq"\nDato Rotulado: b"); print-rotulo(&persona); return(0); . void print-rotulo(struct rotulo *pptr) { print4"\n%s %S%s\n%s b%shtt, pptr-> nombre.apellido, pptr-> nombre.nombre1, pptr-> nombre.nombre2, pptr-> direccion.calle, pptr-> dieccion.ciudad); 1 43 Area de Compubci6n Universidad de La Serena Prof.Dr. Eric JeltschF. int leer-rotulo(struct rotyio *pptr) /* parametro puntero *pptr, el que apunta a un objeto de tipo struct rotulo */ (int x; printqnIngrese<Apellido-Primer(nombre1>Segwido(nombre2)>, EOF para salir: "); x = s c ~ ?%S s %s%*cl1,pptr->nombre.apellido, pptr->nombre.nombre 1, pptr->nombre.nombre2); if (FEOF) retuni FAL; printqWIngrese Direccion: "); gets(pptr->direccion.calle); printq"1ngrese Ciudad: "); gets(pptr->direccion.ciudad); /*scanf("%sn,pptr->direccion.ciudad);*l retuni VER, M --Datos Rotulados para una PersonaIngrese Jeltsch Ingrese Ingrese el nolbre<Apellido-Priner(norbrc)-Segundo(norbrc)>, Eric Roberto Direccion: nindo Nuevo 29 Ciudad: La Serena EOF para salir: Dato Rotulado: Jeltsch Eric Roberto nindo Hieuo 29 La Serena 44 Universidad de La Sereiia Area de Computaci6n M Dr.Eric JeltschF. ARREGLO DE ESTRUCTURAS Los ejemplos de inventario y rotulos son ejemplos de registros. Como en casos previos necesitamos almacenar una lista de items, pudiendo usar un array como nuestra estructura de dato. En este caso los elementos del array son estructuras de un tipo especifico. Por ejemplo, struct inventario( int partidamo; float costos; float precios; 1; struct inventario tabla4); la cual define un array con cuatro elementos, cada uno de los cuales es de tipo stmct inventario, es decir cada uno está en la estructura inventario. Pudiendo pensar entonces en una representación tabular de una base de datos, la que puede verse así: partida número costo precio - 123 ( 10.00115.001 tabla[O]->l equivalente a *(tabla) (tabla + 1) -tabla[2]---->l tabla[3]-->l 1 1 1 1 1 1 ---- (tabla + 2) (tabla + 3) Con esto en la mente podemos extender nuestro programa de rotulado de direcciones, para leer e imprimir un listado de rotulos. l l #include<stdio.h> #define MAX 20 #define FAL O #define VER 1 struct nombre-re{ char apellido[l5]; char nombre1[l5]; char nombre2[15]; 1; struct d i r e v e ( char calle[25]; char ciudad[15]; 1; struct rotulo( struct nombre-re nombre; struct direc-re direccion; Programacibn en C (Tutoriai) (conthaci6n) Prof. Dr.Enc JeltschF. void print-rotulo(stmct rotulo *personaptr); int leer-rotulo (struct rotulo *personaptr); main() { struct rotulo personajMAX); int i, n; printf("** *Rotulas -YO** *ui\nN); n=O; /* leer los rotuloss/ while(n < MAX && leer-rotulo(kpersona[n*])); if (n=MAX) printf("\nRotulo Ileno- Imprima: h"); else -n; /* EOF encontrado para el ultimo valor de n*/ /* imprime los roídos*/ printf("\nDatos Rotulados:\n"); for(i=O; i<n; i*) print-rotuio(&persona[i]); return(0); 1 void print-rotulo(struct rotulo *pptr) { printq"\n%s %S %s\n%s ui%s\n", pptr-> nombre.apellido, pptr-> nombre.nombre 1, pptr-> nombre.nombre2, pptr-> direqion.calle, pptr-> direccion.ciudad); 1 int leer-rotulo(stmct rotulo *pptr) (int x; printflUIngreseel nombre<~~ellido-~rimer(nomb~e)-Seg~ndo(no), EOF para salir: "); x=scanf("%s %S%s%*cU,pptr-)nombre.apellid~, pptr->nombre.nombre 1, pptr->nombre.nombreZ); if (FEOF) r e t m FAL; printquIngreseDireccion: "); gets(pptr->direccion.calle); printqUIngreseCiudad: "); gets(pptr->direccion.ciu&d); /*scanf("%sU,pptr->direccion.ciudad);*l retum VER, - 46 universidad de La Sereaa Arca de ~mmtaci6n Prof. Dr. Enc Jelisch F. Praganaci6n en C flutaíai) (continuación) A continuación se visualiza la interface solución Ingrese e l nodre<Rpellido-Prirer(norbre)-Segundo(noiibre)>, J e l t s c h PaDlito Hannes Ingrese Direccion: Ilindo Nucuo 29 Ingrese Ciudad: La Serena Ingrese e l noilbre<8pellido-Prirr(noiibre)-Segundo(norbre)>, Decker Uera m r i a Ingrese Direccion: Ilundo Nueuo 29 Ingrese Ciudad: La Serena Ingrese e l norbreiftpellido-Prirr(norbre)-SeguRdo(na&re)>, Datos Rotulados: EOF para s a l i r : EOF para s a l i r : EOF para s a l i r : J e l t s c h Eric Roberto Cbndo h e w o 29 L I serena J e l t s c h P a b l i t o Hannes Wndo Nuevo 29 La serena Decker Uera n a r i a ILindo Nuwo 29 ~a serena .- . - #include<stdio.h> #define MAX 10 /* Este archivo wntiene est~~cturas y definición de tipos de datos necesarios para el programa en archivo sueldoreg.c*/ struct nombrereg{ char apellido[l S]; char nombre1[1 S]; char nombre2[1 S]; 1; E I struct sueldoreg{ int id; stnict nombrereg nombre; float horas; float mon; float regular, float sobre-tiempo; float gana; float tasa; float neto; 47 Area de Computaci6n Universidadde La Seraia Prof. Dr. Eric Jeltsch F. typedef stnict sueldoreg sueldoreg; void print-resumen(doub1e gana, double tasa); int leer-reg(sue1doreg sueldo[], int lim); void print-reg(sue1doreg sueldo[], int n); double cal-reg(sue1doreg sueldo[], int n, double *tasaptr); void leer_nombre(sueldoreg sueldo[], int i); void print-nombre(sue1doreg sueldo[], int i); /*este programa calcula el sueldo y los imprime. Cada dato "record" es una stnict, y el calculo es un arreglo de stnict. El impuesto a la renta es 15% si gana a lo más 50000,28% si gana a lo más 100000, y 33% si gana más de esa cantidad. Un reporte final imprime la salida de los sueldos a pagar y los impuestos que se retienen*/ maino ( int n*; sueldoreg sueldoFIAX]; double gana, tasa*; p r i n r ***Programa Sueldo***\nuiW); n=leer-reg(sueldo, MAX); gana-al-reg(sueldo, n, &tasa); print_reg(sueldo, n); print-resumen(gana, tasa); r-(0); 1 /*esta función imprime el resumen final*/ void print-resumen(doub1e gana, double tasa) print@"\n***RESUMEN***\dn"); printqnSueldoTotal=$%8.2f; Tasa total=$%8.2f\n", gana, tasa); 1 /*lee los sueldos de entrada hasta EOF o hasta lim record haya sido leído*/ int leer-reg(sue1doreg sueldo[], int lim) { int i, n, x; float z; void leer-nombre(sue1doreg sueldo[], int i); for ( i 4 ; iclim; i*) { prinflnNum-IDIEOF: "); x = s ~ " % d % * c n&n); , if ( n-EOF) retum i; sueldo[i]. id=n; leer nombre(sueldo, i); priny@"~oras Trabajadas: "); x=scanf("%f%*c", &z); 48 - Universidadde La Serena Area de C o b 6 n Prof. Dr. Eric Jeltsch F. sueldo[i] .horas=z; printqWRazónde Pago: "); x=scanq"%Ph*c", &z); sueIdo[i].razon=z; /* esta función lee un nombre según los campos que tenga*/ void leer-nombre(sue1doreg sueldo[], int i) ( prinflUApellido: "); gets(sueldo[i].nombre.apellido); printf("Primer nombre: "); gets(sueldo[i]. nombre. nombre1); printqWSegundonombre: "); gets(sueldo[i].nombre.nombre2); 1 /* imprime el nombre*/ void print-nombre(sue1doreg sueldo[], int i) ( printfTMNombre:%S %S %suiW,sueldo[i].nombre.apellido, sueldo[i].nombre.nombre1, sueldo[i] .nombre.nombreZ); 1 /* imprime n record de sueldos*/ void print-reg(sue1doreg sueldo[], int n) { int i; void print-nombre(sue1doreg sueldo[], int i); printfT"h***Reporte Sueldo***\nuiW); for( i=O; i<n; i U ) ( printRW\nNum-ID:%duiW,sueldo[i]. id); print-nombre(sueldo, i); pnntRnHoras Trabajadas: %8.2f ",sueldo[i].horas); printf('Razón de Pago: %8.2fh ",sueldo[i]. razon); printq"PAGO\nH); pnntqWRegular:%8.2f, Sobretiempeh8.2f, ",sueldo[i].regulat, sueldo[i].sobre-tiempo); printfT"Gana: %8.2f, Neto-4h8.2fh",sueldo[i].gana, sueldo[i].neto); printRUTasa=%8.2f\n",sueldo[i].tasa); 1 1 Areade Computación Universidad de La Serena 49 - Prof. Dr.Eric JeltschF. /*esta función computa sueldos regulares y sobretiempo y la tasa de impuesto que se retiene, según lo expuesto al comienzo del programa*/ double cal-reg(sue1doreg sueldo[], int n, double *tasaptr) { int i; double gana=O; *tasaptr=O; for( i=O; i<n; i*) { if (sueldo[i].horas <= 40) ( sueldo[i].regula~sueldo[i].gana=sueldo[i].horas*sueldo[i].razon; sueldo[i].sobre-tiempo*; 1 else( sueldo[i].regular==O*sueldo[i].razon; sueldo[i].sobre-tiempo=(sueldo[i].horas 1 - 40)*1.5 *sueldo[i].razon; sueldo[i] .gana=sueldo[i].regular + sueldo[i].sobre-tiempo; if(sueldo[i].gana<=500) sueldo[i].tasa=O.15*sueido[i].gana; else if (sueldo[i].gana<= 1000) sueldo[i].tasa=O.Z8*sueldo[i].gana; else sueldo[i].tasa=0.33*sueldo[i].gana; gana+=sueldo[i].gana; *tasaptr+=sueldo[i].tasa; sueldo[i].neto=sueldo[i].gana sueldo[i]. tasa; return gana; - Segundo nombre: n a r i a Horas Trabajadas: 50 16.5 Razón de Pago: nim-IDfEOF : m R e p o r t e Sueldonin-ID: 17 Nonbre: j e l t s c h c r i c roberto Horas Trabajadas: a8.80 ~ a z d nde Pago: 12.80 PR60 Regular: 456.80. Sobretieipom 0.00. Cana: 456.00. Tasa= 68.40 nia-ID: 1 0 Norbre: decker vera n a r i a Horas Trabajadas: 50.81 Razón de Pago: 16.50 Paco Regular: 668.00, Sobrctierpo2h7-50, Gana: 987.51, Tasa= 254.10 Sueldo ~ o t a l = $1363.50: - Tasa t o t a l = $ 50 Universidadde La Serena Neto= .a8?.60 kto= 658.40. 322.50 Afea de Compta~i6n en C Vutoriai) (continuación) Pro-6n Prof. Dr.Enc Jeltsch F. UNION En algunas aplicaciones es posible mantener la información de una o de dos formas alternativas. Por ejemplo, supongamos que queremos guardar la información para persona y la persona puede ser identificada ya sea por el nombre ó por el número de su identificador, pero NUNCA ambas al mismo tiempo. Otro ejemplo, se presenta en el registro civil cuando quiere sacar carnet, le piden el carnet....y Ud. NO lo tiene....entonces le pueden preguntan como se llama, y a través del nombre decirle el número que tiene. La estructura en C que permite esta gracia es la UNION, la cual es de particular importancia si desea mantener un larga lista de personas, tales como calculo de sueldo para una gran compañia. La reserva de memoria en la unión no significa reservar memoria para cada uno de los campos, sino que se reserva memoria para el campo mayor y esta zona puede ser ocupada por UNO de los campos. struct articulo ( char cod-art[10);/* 10 bytes*/ char nombre[20);/*20 bytes*l char des[30); /*30 bytes*/ float precio; /* 4 bytes*/ int existencias;/* 2 bytes*/ char codqrov[lO);/* 10 bytes*/ char notas[30);/* 30 bytes*/ );/* articulo entonces ocupa 96 bytes*/ Sin embargo, mediante UNION struct articulo-union ( char cod-art[lO);/* 10 bytes*/ char nombre[20);/*20 bytes*/ char des[30); /*30 bytes*/ float precio; /* 4 bytes*/ int existencias;/* 2 bytes*/ char codgrov[l O);/*10 bytes*/ char notas[30);/* 30 bytes*/ );/* articulo entonces ocupa 30 bytes*/ En este ejemplo se reservará espacio para un string de 30 caracteres. DENTRO de ese espacio puede colocarse un string de 10 caracteres, uno de 30, un float ó un entero. Es decir todos comparten la misma dirección. Es responsabilidad del programador saber QUE hay almacenado en un momento concreto. Una manera de saberlo es main() ( articulo-union articulo-1 ; articulo-1.precio=1000;/*se ha almacenado un precio*/ ---- printfrlo que hay en la UNION es: %W,articulo-1.precio); 1 Area de Computación Universidad de La Serena 51 - Rof. Dr.Eric Jeltsch F. UNION es usada en aplicaciones que requieren interpretaciones múltiples para un segmento de memoria. Pero más comúnmente, ella es usada para conservar un espacio de memoria para ser usado por una variedad de tipos. union { int id; char nombre[25); ) persona; /* persona tiene dos campos, un string y un integer. Si el nombre es ingresado usamos persona para almacenar string, y si el número id es ingresado usamos persona para almacenar el entero.*/ Se pueden definir a través de rotulos ( tag ) union humano { int id; char nombrer25); 1 persona; También es posible definir union humano { int id; char nombrer25); 1; union humano persona, *persptr; Ejemplo: persptr=&persona; persona.id=12; if ( persptr->id -12) 52 Universidad & La Serena Area & C o d ó n ñogramaci6nen C (Tu!oriai) (continuacih) Prof. Dr. Eric Jeltsch F. ESTRUCTURAS DE DATOS EXTERNAS (Archivos) Objetivos: 1) Conocer y comprender el concepto de Archivo 2) Distinguir los distintos tipos de Archivos, ventajas y desventajas, y saber cuando utilizarlos 3) Utilizar los conceptos de la Programación Estructurada en la construcción de funciones generales para el trabajo con archivos en C. 4) Aplicar los conocimientos hasta ahora aprendidos para el diseiio y construcción de aplicaciones que trabajen con archivos. 5) Integrar el trabajo con archivos en la metodología de construcción de aplicaciones. En la mayona de las aplicaciones, sobretodo en gestión es necesario almacenar la información en forma permanente, hasta ahora toda la información es volátil, es decir terminada su ejecución desaparecen y la información contenida desaparece. Para resolver este problema es que se necesita estructuras de datos externas al programa, en donde dichas estructuras se almacenen en cintas, disquetes, cd-rom etc. En C la estrucutra de dato externa básica son los archivos. A cada uno de los componentes de un archivo se les llama registro Terminología con Archivos a) Creación: b) Apertura: c) Ciene: d) Borrado: e) Lectura: f) Escritura: g) Cambio de Nombre: Clasificación de los Archivos(según el usuario) a) Ejecutables b) Código c) Datos Clasificación según los Informáticos Permanentes, la cual cobija información que no varía ó varía muy poco Constantes: Los datos permanecen prácticamente constantes, nombre de provincias... Maestros: Contienen la información actualizada en un determinado momento. Históricos: Contiene información ya utilizada y se mantienen como fines de consultas o estadisticas o para realizar una contaduría computacional, ej.. transacción bancaria 53 Area & Computaci6n Universidad de La Serrsia Prof. Dr.Eric Jeltsch F. de movimientos, contiene la información que se utilizará para actualizar los archivos maestros de maniobra, son archivos temporales que se crean y sólo existen en tiempo de ejecución del programa Según la forma de organización de los archivos se clasifican como: Organización contigua: todos los sectores que forman un archivo están contiguos. Desaprovechando los huecos que quedan al borrar un archivo, la ventaja radica en poder accesar bajo cualquier método u organización e Organización encadenada: donde el directorio tiene un puntero al primer sector y cada sector a su siguiente. Solucionando así el problema de los huecos, pero a cambio no permite saber a priori la longitud de archivo. Pero sobretodo obliga a recorrer todos los elementos anteriores e Organización índexada se guarda una lista de los sectores que forman el archivo y cuando hace falta se consulta. Desde el punto de vista del desarrollador de aplicaciones, es más representativo clasificarlos por su mhtodo de acceso, es decir por el mecanismo por el que se accede a sus elementos, según esto son: Secuenciales, significa que los elementos están almacenados sin ninguna indexación, de manera que la inserción de nuevos elementos se hace al final del archivo, y que para leer un elemeneto se necesita leer todo el archivo. Directos, la información está ya sea contigua o indexada, de manera que para acceder a algún elemento no necesita recorrerlo todos. Secuenciales indexados, es una combinación de los dos anteriores. Archivos en C Un archivo en C es una estructura de datos que se declara con la palabra FILE, y donde la biblioteca stdio se encarga de soportar Sintaxis FILE *archivo; Funciones Básicas de Acceso a los Archivos fopen , permite abrir un archivo Sintaxis #include<stdio.h> fopen( char *nombre, char *tipo); *nombre, es una cadena de wacteres que especifica el nombre del archivo y el tipo es otra cadena, de uno o dos caracteres que especifica que tipo de operación V 0 se realizará sobre el archivo, los posibles tipos son: 54 - Universidadde La Serena Area de Con4mtaci6n Rof. Dr. Eric Jeltsch F. TIPO DESCRIPCION Abre para lectura. El archivo existe previamente sino error Abre para escribir, sino existe lo crea, y si existe destruye ant. Abre el archivo para escritura desde el final del mismo, es decir a aiiade. Si el archivo no existía crea uno nuevo. rtAbre el archivo tanto para leer como para escribir por el comienzo. Debe existir el archivo, si no se produce un error w+ Abre el archivo tanto para leer como para escribir desde el comienzo. Si ya existía el contenido previo se borra. Si no existía, se crea. Abre el archivo tanto para leer como para escribir por el final. Si a+ no existía se crea un archivo nuevo. En C se distingue entre dos tipos de archivos básicos en el momento de almacenar la información, ellos son los de caracteres y los binarios, los primeros son archivos de texto y los segundos son archivos formados por estructuras, de ahí que tal vez parte de su contenido pueden tener campos que no sean cadenas de caracteres. Un ejemplo de como detectar el error producido al abrir un archivo es mediante: #include<stdio.h> void main() ( FILE *archivo; archivo--foopen("inventario.dat", "r"); if (archivo= NULL)( printvNo se pudo abrir el archivo"); else p n n w se ha abierto el archivo"); /* aquí se realizan las operaciones con archivo*/ 1 fclose(archivo); /* se cierra el archivo*/ 1 fopen construye un stream, un canal de leer y escribir y un buffer, que es un aimacén temporal, devolviendo un puntero a dicho canal , en cambio fclose es la encargada de romperla conexión entre el puntero y la estructura extema, liberando de esta manera el puntero, lo que se conoce como cerrar el archivo. Al invocar a esta fúnción también se libera el buffer correspondiente 55 Area de Compitaci6n Universidad de La Sereaa Programación em C (Tutoriaí) (continuación) Prof. Dr.Eric Jeltsch F. Las funciones getco y p u t a Una vez que ya se ha abierto un archivo, lo siguiente es poder leer y escribir en el. En el caso de archivos de texto se usan las macros getc() y putc() (también'llamadas fgetc() y fputco),que permiten leer y escribir un caracter en un archivo previamente abierto. Sintaxis: #include<stdio.h> int getc(FiLE *archivo); int putc(int c, FILE *archivo); ', Las funciones fgetso y fputso Son equivalentes a las funciones gets() y puta, excepto que ahora la fbente NO es stdin o el stdout, sino el archivo que ingresa como argumento. fgeta, lo que devuelve la fiinción es la cadena de caracteres leida en caso de lectura comecta o NULL si ha existido un error. Por su parte fputs() devuelve el último caracter escrito si todo el proceso ha ido bien, o el caracter EOF si ha existido algún error. Sintaxis: #include<stdio.h> char *fgets(char *cadena, int n, FILE *archivo); int fputs(char *cadena, FILE *archivo); #include<stdio.h> #define MAX 100 #include<stdlib.h> float proc-array(int examen[], int lim, int *pmax, int *pmin); main() { int max, min, n, lim=O,notas-exam[MW; char infile[l S]; float promed; FTLE *inp; printfln***Notasde Examenes:Promedio,Max, Min***\n\nW); prinq" Archivo Entrada:"); scanf("%sn,infile); inp-fopen(infrle, "r"); if (!inp) { printf("No disponible archivo de entradah"); exit(0); while (lim < MAX && fscaainp, "%dN,&n) != EOF) notatasexam[lim*]=n; fclose(inp); if (lim=O)exit(0); promed=proc-my(notastaSex8m,lim, &max, &min); printf("Promedi~+?CMáximo=?hd, Mínimo=??dui",promed, rnax, min); retum(0); 56 Universidad de La Serena Area de Computación Programación en C (Tutoríal) (continuación) Prof. Dr.Eric Jeltsch F. float proc-array(int ex[], int lim, int *pmax, int *pmin) { int i,max, min; float suma=O.O; max=min=ex[O]; for (i=O; i<lim;i++) { suma+=ex[i]; mr--ex[i] > max ? ex[i] : max; min=ex[i] < min ? ex[i] : min; ) *pmax=max; *pmin=min; return sumal lim; 1 /*comentarios: El driver abre el archivo de entrada y lee los datos en el array notas-examen, el número de elementos es contado por lim. Si lim =O se termina el programa; de otra manera, el programa invoca a proc-mayo para procesar el array según promedio, rnax y min. En la llamada a proc-array, main() pasa como argumentos notasexamen, lim y punteros a max y min. La función proc-array() inicializa valores de variables locales, max y min al primer elemento del array examen[), en la travesía va acumulando y actualizando los datos. W t a s de Exam?nes:Pronedio, M Hax, Min- Archivo Entrada:linda,doc Proiredio=58.187S@@. ndxim=9@. idnim=l2 - 57 Area de Computación Universidad de La Serena Prof. Dr.Eric Jeltsch F. Open a File 58 - Universidad de La Serena -1 1 Area de Computación Prof. Dr.Eric Jeltsch F. #define MAX 10 #include<stdio.h> #includ&ctype.h> /*para isdigitO*/ #include<sidlib.h> /* Este programa lee caracteres desde un archivo strems y cuenta el número de ocurrencias de cada dígito */ main() ' { int f i e c - d i g w , i; signed char ch; FILE *fin;/*un archivo de tipo puntero es declarado, fin es de tipo FILE * FILE está definido en <stdio.h> */ printf("***Ocurrenciade digitos***\nuin); for ( i 4 ; i < MAX; i*) 6ec-dig[i]=O; /*después de inicialii a cero el archivo test.doc, es abierto usando la función librería estandar fopen()*/ fin=fopen("linda.doc", "r");/* la función fopen() toma dos argumentos: un string el cual le da el nombre al archivo fisico, y el segundo especifica el modo ("r" para leer) para el archivo de entrada*/ iq!fin) { printf("N0 habilitado el archivo: test.doc\n"); exit(0); /* si el archivo no puede ser abierto */ 1 while ((ch=getc(fin)) !=EOF) { /* si el archivo es abierto e.d. fin NO es NULL es accesado a ch a través de getc(), esta función leerá el stream accesado por el archivo puntero, fin */ if (isdigit(ch))/* cada caracter es leído para ver si es un dígito*/ fiec-dig[ch 'O']*;/* si lo es lo cuenta y lo incrementa*/ - 1 fclose(fin); /* alcanzando el fin de archivo, el archivo se cierra */ for ( i 4 ; i< MAX; i*)/* para imprimir lo acumulado en el array*/ printq"Existen %d ocurrencias de %d en la entradaui", 6ec-dig[i], i); rm(0); 1 59 Area de (bmpmci6n Universidad de La Serena Prof. Dr.Eric Jeltsch F. Existen Existen Existen Existen Existen Existen Existen Existen Existen Existen 1 1 5 4 2 3 4 4 4 4 ocurrencias ocurrencias ocurrencias ocurrencias ocurrencias ocurrencias ocurrencias ocurrencias ocurrencias ocurrencias de de de de de de de de Be de D 1 2 3 4 5 6 7 8 9 en en en en en en en en en en la la la la la la la la la la entrada entrada entrada entrada entrada entrada entrada entrada entrada entrada #define MAX 10 #include<stdio.h> #include<ctype.h> /.*para isdigit()*/ #include<stdlib. h> rnaino FILE *input, *output; char enf'íle[l5], safile[l5]; signed char ch; printqn** *Programa Copiador de Archivos- Char YO***\nuin); printq"Archiv0 Input: "); sc@"%sn, enfile); printq"Archiv0Output: "); sCanq"?/os", dile); input=fopen(enfile,"r"); iqinpu-NüLL) ( printf(n* **NO puedo abrir Archivo Input** *\n"); exit(0); 1 output=fopen(safile, "w"); iqoutput=NüLL) { Universidad de La Serena Area de Computaci6n Prof. Dr. Eric Jeltsch F. - printqW***NOpuedo abrir Archivo Output***ui"); exit(0); 1 while ((ch=getc(input)) !=EOF) /*es válido ch=getc(stdin);*/ /* es válido putc(ch, stdout)*/ putc(ch, output); fclose(input); fclose(output); printqWSe ha completado la copiaui"); rm(0); 1 17 =-fVograma Copiador de Archivos- Char 110Archivo Input: 1inda.dac Archivo Oütput: p a b l i t o - ~ O C Se ha colpletado l a copia Area de Computación Universidadde La Serena Progcunaci6n en C (Tuioriai) (ooníiwaci6n) r---- Universidad de La Serena Prof. Dr.Eric Jeltsch F. -----u-- Open a File -1 Area de C o e 6 n