Estructura de Datos y de la Información I, 2008

Anuncio
Estructura de Datos y de la Información I, 2005-2006 :: Práctica 2
Página 1 de 7
Estructura de Datos y de la Información I, 2008-2009
Escuela Politécnica Superior, UAM
Práctica 2: Manipulación de cadenas de caracteres en C y definición de
nuevos TADs
Objetivos
1. Profundizar en elementos básicos de programación (control de bucles, gestión de errores,
I/O básicos, reusabilidad del código).
2. Iniciarse en la organización multiarchivo del código y en el uso de proyectos en MSVC++.
3. Iniciarse en la definición de nuevos tipos abstractos de datos (TADs) y en su
implementación y uso.
4. Manejar diversos aspectos esenciales de la programación C:
{
Gestión de cadenas de caracteres: operaciones elementales.
{
Definición y manejo de estructuras.
{
Uso de punteros.
Normas
Los programas que se entreguen deben:
z
z
z
z
z
Estar escritos en ANSI C siguiendo las normas de programación establecidas.
Utilizar las plantillas de código suministradas para los ficheros de código "*.c" y las
cabeceras "*.h".
Compilar sin errores ni "warnings" con el máximo nivel de advertencias en
Microsoft Visual C++ 6.0.
Ejecutarse sin problema en una ventana de comandos de Windows.
Incorporar un adecuado control de errores, es justificable que un programa no admita
valores inadecuados, pero no que se comporte de forma anómala con dichos valores.
La memoria que se entregue debe:
z
Elaborarse siguiendo las normas sobre elaboración de memorias.
z
Utilizar la plantilla para la memoria suministrada.
La entrega se realizara en dos fases, siguiendo escrupulosamente las instrucciones indicadas
en la normas de entrega de prácticas:
z
Entrega electrónica mediante la Página de Entregas Web de la Escuela de todos
los fuente, el proyecto y la memoria de la práctica, antes del comienzo de la clase o
examen correspondiente al día de entrega (sin olvidar seguir normas de entrega de
prácticas).
Estructura de Datos y de la Información I, 2005-2006 :: Práctica 2
z
Página 2 de 7
Entrega física de una copia impresa de la memoria incluida en la entrega
electrónica, al comienzo de la clase o al final del examen correspondiente al día de
entrega.
Las fechas de entrega son las siguientes:
z
z
Los alumnos de Evaluación Continua, según el calendario establecido, cada pareja el
día de prácticas correspondiente a su grupo.
Los alumnos de Evaluación Final, el día del examen final de la asignatura en junio.
Preliminares
Cadenas de caracteres en C
Empleando K&R como referencia, una cadena de caracteres constante es una secuencia de cero
o más caracteres encerrados entre comillas.
"una cadena", "otra cadena\n", "" (cadena vacía)
Las comillas no forman parte de las cadenas y sólo sirven para delimitarlas, mientras que las
secuencias de escape de caracteres (\n, \t,…) sí pueden aplicarse en ellas.
Técnicamente, una cadena es una tabla (array) de caracteres, cuya representación interna tiene
un carácter nulo '\0' al final, de modo que el almacenamiento físico requerido es 1 más del
número de caracteres escritos entre comillas.
"una cadena"
(longitud = 10 caracteres)
u
n
a
c
a
d
e
n
a
\0
a
\n
(almacenamiento = 11 posiciones de memoria)
"otra cadena\n"
(longitud = 12 caracteres)
o
t
r
a
c
a
d
e
n
\0
(almacenamiento = 13 posiciones de memoria)
De este modo, hay que tener cuidado al distinguir entre un carácter y una cadena que contiene
un solo carácter: 'x' no es lo mismo que "x". El primero es un carácter, es decir, un entero
utilizado para producir el valor numérico de la letra x, mientras que el segundo es un array de 2
caracteres: 'x' y '\0'.
Ejercicios
1. Funciones de manipulación de cadenas de caracteres.
Estructura de Datos y de la Información I, 2005-2006 :: Práctica 2
Página 3 de 7
Implementar las siguientes funciones de manipulación de cadenas (afines a las de string.h) en
un archivo myString.c y guardar sus prototipos en otro archivo myString.h. Para ello:
z
z
z
Suponer que las cadenas se almacenan en tablas de tamaño fijo MAX_STR (establecer el
#define apropiado).
Pensar cuáles son los parámetros de entrada y el tipo de retorno de cada función.
Implementar las funciones, efectuando en cada una de ellas el control de errores
apropiado para evitar desbordamientos en las cadenas. No se podrán emplear las
funciones de manejo de cadenas de la librería de C (string.lib)
Funciones a implementar:
z
z
z
z
myStrlen: recibe una cadena de caracteres y devuelve su longitud (-1 en caso de error).
myStrcpy: recibe dos cadenas, copia el contenido de la 2ª en la 1ª, y devuelve 1 en caso
de ejecución correcta ó -1 en caso de error.
myStrcmp: compara el contenido de dos cadenas, devolviendo un número negativo (la
diferencia que las separa) si la primera es menor que la segunda, un número positivo si la
primera es mayor que la segunda y 0 si ambas son iguales. Los caracteres deben
compararse uno a uno.
myStrncat: recibe dos cadenas y un entero "n", y concatena hasta "n" caracteres de la 2ª
cadena al final de la 1ª, devolviendo la 1ª (modificada) si la ejecución es correcta, o NULL
en caso de error.
2. Manipulación de cadenas de caracteres.
Desarrollar un programa con una función main que, empleando 3 cadenas sobre tablas de un
tamaño fijo MAX_STR y las funciones de mystring.h:
z
Pida al usuario y lea por teclado el contenido de las tres cadenas (mediante la función
estándar gets).
z
Concatene la primera y la segunda
z
Copie el contenido de la tercera en la segunda.
z
Imprima por pantalla (usando printf) el contenido y la longitud de todas ellas.
z
Imprima el resultado de comparar la tercera con el resto.
Entrega: proyecto correspondiente
correspondientes a los ejercicios 1 y 2.
al
ejercicio
2,
incluyendo
los
ficheros
3. Definición de nuevos TADs e implementación mediante estructuras.
Un profesor de la EPS desea manejar de forma cómoda los datos de su grupo de EDI. Para
facilitarle dicha tarea, se van a definir 2 nuevos tipos abstractos de datos: grupo y alumno.
El profesor desea manejar los siguientes datos:
Estructura de Datos y de la Información I, 2005-2006 :: Práctica 2
z
z
Página 4 de 7
Para cada alumno, su nombre y su nota.
Para el grupo, su nombre, el número de alumnos que lo forman, los datos de los alumnos,
la nota media del grupo, la mejor nota, la peor nota, el mejor alumno y el peor alumno.
Definir los TADs grupo y alumno e implementarlos definiendo las correspondientes
estructuras de datos en C. Crear los correspondientes ficheros grupo.h y alumno.h
Para que el profesor pueda trabajar con los datos de los alumnos, se van a definir una serie de
primitivas asociadas a cada TAD.
En relación con cada alumno, las primitivas permitirán (cada una de estas funcionalidades se
corresponden con una primitiva diferente):
1. Almacenar nombre y nota del alumno: estos datos se solicitan al profesor en esta
primitiva con un mensaje en la pantalla y el profesor los introducirá por teclado.
2. Conocer la nota del alumno: quien llame a esta función desea conocer la nota del alumno,
por lo que esta función debe devolver dicha nota.
3. Conocer el nombre del alumno: quien llame a esta función desea conocer el nombre del
alumno, por lo que esta función debe devolver dicho nombre.
4. Comparar dos alumnos: serán iguales si su nombre es el mismo, sean cuales sean sus
notas, y distintos si difieren en el nombre.
5. Imprimir datos de un alumno: se mostrarán por pantalla
6. Copiar datos de un alumno a otro
En cuanto al grupo, se desea poder:
1. Inicializar datos del grupo, asignándole un nombre e inicializando los valores de la nota
mejor, peor y media, así como los del mejor y peor alumno.
2. Comprobar si un alumno está en un grupo.
3. Comprobar si un grupo está lleno.
4. Comprobar si un grupo está vacío.
5. Añadir alumno al grupo. Comprobar previamente que el grupo no está lleno, y que el
alumno no estaba ya en el grupo (si estaba, no hay que añadirlo de nuevo, aunque la
nota sea distinta).
6. Calcular mejor nota, peor nota, nota media, mejor alumno, peor alumno
7. Imprimir datos del grupo (sólo si el grupo no está vacío), incluyendo su nombre, el
número de alumnos que lo forman, la información de cada uno de ellos y los demás datos
sobre notas (media, mejor, peor, mejor alumno, peor alumno).
Implementar las primitivas correspondientes a los TADs alumno y grupo en los
ficheros grupo.c y alumno.c correspondientes. Usar la biblioteca mystring para el
trabajo con cadenas de caracteres.
Para facilitar esta implementación, se proporcionan los prototipos de las primitivas
de:
alumno:
Estructura de Datos y de la Información I, 2005-2006 :: Práctica 2
Página 5 de 7
1. status leeAlumno (alumno * al);
2. float getAlumnoNota (alumno * al);
3. char * getAlumnoNombre (alumno * al);
4. status printAlumno (alumno * al);
5. int alumnoCmp (alumno * al1, alumno * al2);
6. alumno * alumnoCopy (alumno * al1, alumno * al2);
grupo:
1. status iniGrupo (grupo * a, char * nombre);
2. boolean estaAlumnoGrupo (alumno * al, grupo * gr);
3. boolean grupoLleno (grupo * gr);
4. boolean grupoVacio (grupo * gr);
5. status addAlumnoGrupo (alumno al, grupo * gr);
6. status calculaNotas (grupo * gr);
7. status printGrupo (grupo * gr);
Notas:
z
z
Suponed que hay un número máximo de alumnos en cada grupo, MAX_ALUMNOS
(establecer el #define apropiado).
Definid los tipos de datos:
{ status: valores posibles OK y ERROR
{
z
boolean: valores posibles TRUE y FALSE
Implementad las funciones efectuando en cada una de ellas el control de errores
apropiado.
4. Utilización de los nuevos TADs definidos en un programa principal
Desarrollar un programa con una función main que, utilizando los TADs definidos en el ejercicio
anterior en grupo.h y alumno.h:
z
z
z
Reciba como argumentos en línea de comandos el nombre de un grupo y el número de
alumnos del mismo.
Inicialice el grupo.
Pida al profesor los datos de cada alumno, almacenándolos y añadiéndolos al grupo uno
por uno.
z
Calcule los datos.
z
Imprima por pantalla todos los datos del grupo.
Estructura de Datos y de la Información I, 2005-2006 :: Práctica 2
Entrega: proyecto correspondiente
correspondientes a los ejercicios 3 y 4
al
ejercicio
4,
Página 6 de 7
incluyendo
los
ficheros
5. Modificación del programa anterior para lectura/escritura de datos de/en ficheros
Crear un nuevo proyecto inicialmente igual al anterior y modificar los ficheros necesarios para
permitir la lectura y escritura de datos a través de ficheros.
Modificaciones en biblioteca de alumnos:
1. status leeAlumno (alumno * al, FILE * pf); //Lee los datos del alumno de un
fichero ya abierto
2. status printAlumno (alumno * al, FILE *pf); // Escribe los datos del alumno en
un fichero ya abierto
Modificaciones en biblioteca de grupo:
1. status printGrupo (grupo *gr, FILE * pf); // Escribe los datos de todo el grupo
en un fichero ya abierto
Modificaciones en la función main:
z
z
z
z
Recibe 2 argumentos de entrada en línea de comandos: nombre del fichero de entrada y
nombre del fichero de salida.
Lee del fichero de entrada el nombre del grupo y el número de alumnos (en la misma
línea)
Inicializa el grupo
Lee del fichero de entrada los datos de cada alumno, almacenándolos y añadiéndolos al
grupo uno por uno.
z
Calcula los datos de notas mejores, peores, media, etc.
z
Imprime en el fichero de salida todos los datos del grupo.
Ejemplo de fichero de entrada:
Grupo-1B
3
Alicia 7.28
Antonio 3.75
Lucia 6.00
Ejemplo de fichero de salida:
Grupo-1B
3 alumnos:
Alicia 7.28
Antonio 3.75
Lucia 6.00
Nota media: 5.68
Estructura de Datos y de la Información I, 2005-2006 :: Práctica 2
Página 7 de 7
Mejor nota: 7.28, alumno: Alicia
Peor nota: 3.75, alumno: Antonio
Entrega: proyecto correspondiente al ejercicio 5 incluyendo los ficheros
correspondientes al ejercicio 5 (main) y a los creados a partir del 3 y 4 modificados.
Descargar