Tarea3 - Universidad del Zulia

Anuncio
REPUBLICA BOLIVARIANA
DE VENEZUELA.
UNIVERSIDAD DEL ZULIA
FACULTAD DE INGENIERÍA
DIVISIÓN DE POSTGRADO
COMPUTACIÓN APLICADA
TÉCNICAS DE PROGRAMACIÓN: TAREA 3
Profesor: Ing. Daniel Finol
Nombre: José V. Gómez D.
CI: 10.084.584.
MARACAIBO, MAYO DEL 2006.
I. Tarea 3: Crear un programa que mejore al de la tarea 2, añadiendo las siguientes
modificaciones:
1. No debe prefijarse un límite al número de elementos que pueden incluirse en la
(o las) pila (s).
2. Dentro de las comillas se debe llevar una cuenta aparte de la concordancia de las
llaves ("llaves" = llaves, paréntesis y corchetes): es decir, las llaves dentro de
comillas no afectan la correspondencia de las llaves fuera de ellas; pero dentro
de las comillas sí debe haber correspondencia entre las llaves que cierran y
abren. Al salir de las comillas se debe continuar con la correspondencia que se
llevaba de las llaves externas.
3. El texto se leerá de un archivo cuyo nombre proveerá el usuario como primer
argumento al programa. En caso de no existir argumentos del programa el texto
se leerá de la entrada estándar. Pueden revisar en el libro las funciones de la
biblioteca estándar para manejo de archivos. Algunas de las funciones que
pueden usar son: fopen, fclose, fgetc, fputc.
4. La salida se imprimirá a un archivo cuyo nombre proveerá el usuario como
segundo argumento al programa. En caso de no existir argumentos del programa
el texto se imprimirá a la salida estándar.
5. Tampoco se debe limitar el tamaño de la línea (una manera de hacer esto es leer
un carácter a la vez y procesarlo, en vez de leer línea por línea).
6. El programa principal sólo debe tener acceso a la pila a través de las funciones
correspondientes; es decir, la pila debe estar implementada de tal manera que
quien (el programa o la función) la use no tenga acceso a la estructura de datos
subyacente y así, no pueda, por ejemplo, modificar erróneamente el puntador al
tope y así dañar la estructura al estropear la secuencia. Además esto permite que
se modifique (de ser necesario) la implementación (estructura) interna de la pila
sin que esto afecte el programa o función que la usa; y así este último no tendría
que modificarse.
7. Siempre debe indicarse cuál fue el error (si lo hubo). Por ejemplo: qué llave faltó
cerrar.
8. Cuando falte una llave por cerrar debe indicarse cuál es la posición de esa llave;
además de cuál llave es.
9. El programa imprimirá cada línea precedida de su número seguido de dos puntos
(:) y dos tabuladores.
En estos ejemplos:
1. Estas son externas: { ( [ "aquí estamos dentro de comillas [ { abcd } ] termina"
más texto ] más aún )}.
2. ({Aquí sí hay error(es) "abre ( otro { " })....
3. Aquí hay más texto (etcétera { más todavía "este corchete [ se debe imprimir y
ya no ignorar" ] } ).
4. Aquí hay más texto (etcétera { más todavía "este corchete [ se debe imprimir] y
ya no ignorar" ] } ).
5. Aquí hay más texto (etcétera { más todavía este corchete [ se debe "imprimir] y
ya no ignorar" ] } ).
6. Esta frase: "abre paréntesis (" abre corchete [, abre { etcétera } ] ).
Los errores serían:
1.
2.
3.
4.
5.
6.
Aquí no hay error.
No se cierra la llave dentro de las comillas.
Hay que cerrar el corchete dentro de las comillas.
Hay un corchete cerrado de más (fuera de las comillas.
Hay un corchete cerrado de más (dentro de las comillas).
No se cierra el paréntesis dentro de las comillas.
Consideraciones:




Debe asegurarse de liberar cada segmento de memoria reservado dinámicamente
que ya no se necesite.
Al abrir el archivo debe verificar si realmente se abrió, y, en caso contrario,
informar al usuario y terminar.
El número de columna es el número de caracter de la línea donde se encontró el
error.
Aunque los ejemplos son de una línea el programa debe verificar el texto
completo; no línea por línea; es decir, es correcto que un paréntesis abra en una
línea y cierre en cualquier línea posterior.
Explicación del Código fuente:
En la función main se introducen los argumentos (código ejecutable, archivo de
entrada, archivo de salida) para leer del archivo de entrada carácter por carácter su
contenido ( si no existe lo lee de la entrada estándar) y la salida la coloca en el archivo
de salida ( si no existe lo escribe en la salida estándar).
En línea de instrucción :
FILE *arch_ent,*arch_sal,*fopen();
arch_ent es un apuntador a FILE y la función fopen() devuelve un apuntador a FILE de
la librería estándar .
Si no se puede abrir el archivo de entrada se envía un error a la salida estándar.
Dentro de la función principal -main( )- tenemos:
* Si se cumple argc = =1: Se lee de la entrada estándar y se escribe en la salida
estándar.
Se usa una pila dinámica la cual utilizamos para llevar el control de abrir y
cerrar llaves -“(“, “[“, “{“ , “}”, “]”, “)” – que están fuera de las comillas . Esta pila se
va llenando al obtener el carácter lee ido de la entrada estándar y llamar función push,
luego al leer un carácter de las llaves nombradas se vacía la pila al llamar la función pop
(si se encuentra con un tipo de llave es cuando se introduce o se saca de la pila). Esto se
va canalizando a través de un switch-case.
El primer ciclo while ayuda a verificar e imprimir carácter por carácter del
texto hasta que se consigue un error (llaves no cerradas correctamente) .
Se verifica si se abrió una comilla para no tomarlas en cuenta en la validación
de cierre de los caracteres “(“, “[“, “{“ , “}”, “]”, “)” externos con :
if (comi==2)
comi=0;
if (line[i]=='"' || comi==1 || comi==2){ /*se cumple al estar abierto una comilla*/
if (line[i]=='"' & comi==1)
comi=2;
.
.
.
if (line[i]=='"' & comi==0)
comi=1;
Sino se cumple - if (line[i]=='"' & comi==0) – se lleva el control de las llaves
externas.
Sino no se abrió una comillas o se cerro una comilla abierta se hace la validación
de paréntesis, corchetes y llaves - “(“, “[“,y“{“ - abiertas para ver si están cerradas
correctamente . Esto se hace al conseguir un paréntesis, corchete y llave abierta y
sacando del tope de la pila (con la función pop) el paréntesis, corchete o llave para
compararlos y verificar así que este cerrado correctamente. Si no esta cerrado
correctamente se dice cual es el error y en que línea y columna esta el mismo (esto se
muestra a la salida estándar.
Este conteo, de las líneas y columnas, se hace a través de:
if ((c=='\n') && (i==0)){
printf("%d",linea+1);
printf(":\t\t");
}
if (c!='\n'){
i++;
if (i==1){
printf("%d",linea+1);
printf(":\t\t");
}
printf("%c",c);
}
else{
i=0; linea++;
printf("\n");
}
Al cumplirse - if (line[i]=='"' & comi==0) – se lleva el control de las llaves internas
y se termina de examinar al conseguir el error. Para llevar el control de las llaves
internas (dentro de las comillas) se hace lo mismo que se hizo para las llaves externas.
Usando otra pila dinámica.
Todo esto se hace dentro del primer ciclo while ( las dos pilas se llena y vacían
aquí para llevar el control interno y externo de las llaves) .Esto a su vez esta adentro de
la comparación afirmativa de argc = =1.
* Si argc = =2 o argc = =3: Se lee el archivo de entrada.txt y escribe:
en el archivo de salidat.txt si existe (argc==3, es decir, 3 argumentos) o en la
salida estándar si argc==2 (2 argumentos: código ejecutable y entrada.txt).
Para esto se hace el mismo procedimiento del primer while, utilizando un
segundo while y las instrucciones correspondientes al manejo de “Archivos”.
Aquí también se lleva el control de las llaves externas e internas en forma
separada. Como se explico en el primer while.
La instrucción:
if ((arch_ent=fopen(*++argv,"r"))==NULL){
Abre el archivo de entrada.txt en modo de lectura y verifica si se puede abrir.
La instrucción:
arch_sal=fopen(*++argv,"w");
Abre archivo de salidad.txt en modo de escritura.
Con las instrucciones:
fprintf(arch_sal,":\t\t");
putc(c,arch_sal);
Se imprime en el archive de salida.txt .
Todo esto se lleva en el segundo while como se explico anteriormente.
CODIGO FUENTE DEL PROGRAMA:
TAREA3-JoseG.c
Descargar