IP 2013 Practica 10: Uso de tipos de datos compuestos (Estructuras)

Anuncio
UNIVERSIDAD DON BOSCO
FACULTAD DE ESTUDIOS TECNOLOGICOS
ESCUELA DE COMPUTACION
GUIA DE LABORATORIO # 10
CICLO
02-2013
Nombre de la prácticaa: Uso de datos compuestos (Estructuras)
Lugar de ejecución:
Laboratorio de Informática
Tiempo estimado:
2:30 horas
Materia:
Introducción a la Programación
I. Objetivos
Que el estudiante sea capaz de:
•
•
•
Manejar las operaciones básicas con las cadenas de caracteres en C++
Diseñar e implementar variables de tipos de datos compuestos, llamadas Estructuras (struct).
Implementar diversos tipos de operaciones con estructuras y cadenas de caracteres
II. Introducción
Manejo de Cadenas de Caracteres en C++
En C++, las
as cadenas se consideran como un arreglo de tipo char.
A diferencia de otros lenguajes de programación que emplean un tipo específico (por ej. s t r i n g ) para
manipular un conjunto de símbolos,, en C++
C++se
se debe simular mediante un arreglo de caracteres, en donde la
terminación de la cadena se debe indicar con el carácter nulo ('
('\0'),, observar la imagen siguiente:
Este carácter adicional debe ser considerado al declarar un arreglo de caracteres. Por ejemplo, si se quiere
declarar un arreglo cadena que guarde una cadena de 10 caracteres, se deb
debe
e hacer como:
char cadena[11];
Se pueden hacer inicializaciones de arreglos de caracteres en donde C++ asigna automáticamente el carácter
nulo al final de la cadena, por ejemplo:
char saludo[ 8]="que tal"; //inicializa cadena saludo con cadena “que tal”
___________________________________________________________________________________________
1
La inicialización anterior es equivalente a:
char saludo[8]={'q','u','e', ‘
‘, 't', ‘a’,’l’,'\0'};
Es importante preservar el carácter de terminación NULL (‘ \0 ’), ya que con éste es como C define y maneja las
longitudes de las cadenas. Todas las funciones de la biblioteca estándar de C lo requieren para una operación
satisfactoria.
Operando cadenas de caracteres (Librería string.h)
Los operadores (cin, cout) de los flujos de entrada-salida estándar de C++ permiten manipular el ingreso e
impresión de caracteres. Observe el siguiente ejemplo:
char nombre[20];
cin>>nombre;
cout<<"\n\n\n\t"<<nombre;
Pero c i n tiene problemas cuando se trata de texto que llevan espacios en blanco. El operador cin no hace
comprobación de límites, de manera que es posible que el usuario introduzca más caracteres que los que
pueda almacenar la cadena.
Si intenta introducir desde teclado la cadena “ E s t o e s u n p r u e b a ” , el operador c o u t deja de leer
cuando encuentra el primer espacio en blanco y por lo tanto sólo habrá almacenado “ E s t o ” .
Para cubrir estas deficiencias, Lenguaje C++ consta de una librería exclusivamente para funciones de manejo de
cadenas de caracteres, llamada string.h. Las funciones más comunes son descritas a continuación:
gets(nombreArreglo)
Lee una cadena del teclado hasta que usuario presione tecla intro. Esto significa que permite capturar
secuencias de caracteres que tengan incluidos espacios en blanco
int strlen(const char *s)
Calcula la longitud de la cadena de caracteres.
char *strcpy(const char *dest, const char *orig)
Copia la cadena de caracteres apuntada por orig (incluyendo el carácter terminador '\0') al vector apuntado
por dest. Las cadenas no deben solaparse, y la de destino, debe ser suficientemente grande como para alojar la
copia.
int strcmp(const char *s1, const char *s2)
Compara las dos cadenas de caracteres s1 y s2. Devuelve un entero menor, igual o mayor que cero si se
encuentra que s1 es, respectivamente, menor que, igual a, o mayor que s2.
___________________________________________________________________________________________
2
char *strncat(char *s1, const char *s2, size_t n)
Agrega n caracteres de s2 a s1.
int strncmp(const char *s1, char *s2, size_t n)
Compara los primeros n caracteres de dos cadenas.
char *strncpy(const char *s1, const char *s2, size_t n)
Copia los primeros n caracteres de s2 a s1.
Función fflush
Cuando se requiere utilizar continuamente la función g e t s para capturar una cadena de caracteres con
espacios en blanco o el operador cin, es necesario limpiar/vaciar el buffer del teclado antes de utilizar a gets o
cin, invocando a la función f f l u s h . Observe el siguiente ejemplo:
Sin función f f l u s h ( )
Con función f f l u s h antes de invocar a cin
char nom1[20], nom2[20];
char ape1[20], ape2[20];
char nom1[20], nom2[20];
char ape1[20], ape2[20];
char nombre[80];
cout<<"nom 1: ";
cin>>nom1;
cout<<"\nnom 2: ";
cin>>nom2;
cout<<"\napellido 1: ";
cin>>ape1;
cout<<"\napellido 2: ";
cin>>ape2;
char nombre[80];
cout<<"nom 1: ";
cin>>nom1;
cout<<"\nnom 2: ";
fflush(stdin);
cin>>nom2;
cout<<"\napellido 1: ";
fflush(stdin);
cin>>ape1;
cout<<"\napellido 2: ";
fflush(stdin);
cin>>ape2;
En el código de la izquierda, la 1er vez que se ejecuta cin, el buffer del teclado esta vacio, por tanto, es
necesario usar la función fflush, pero si es necesario usarlo en el resto de invocaciones de cin.
El parámetro stdin significa Estándar Input.
Tipo de dato compuestos Estructura en C++
Con los temas vistos hasta ahora, cuando definimos un arreglo, tenemos a un conjunto de elementos del
mismo tipo de dato. Pero en ocasiones es necesario almacenar información de diferentes tipos de datos la cual
corresponde a un solo objeto, persona o evento del cual se desea obtener la información, Ejemplos: una
agenda, un archivo con un listado de canciones, autor, intérprete, etc. El registro de estudiantes y sus
calificaciones, los valores de un componente eléctrico, los tiempos de una actividad, etc.
Una Estructura es una colección de variables simples, que pueden contener diferentes tipos de datos y se
considera un tipo de dato definido por el usuario. Son también conocidas como Registros.
Ayudan a organizar y manejar datos complicados en programas debido a que agrupan diferentes tipos de datos
relacionados entre sí, y que se les trata como una sola unidad en lugar de ser vistas como unidades separadas.
___________________________________________________________________________________________
3
En C++ la palabra struct se refiere a un tipo de dato que es definido por el usuario. En el caso de los tipos de
datos tales como int, float, char y long son parte integral de C++, por lo que no tiene que escribirse ningún
código que le diga al compilador lo que significan esas palabras.
Una estructura puede considerarse un tipo de dato personalizado. Se pueden agrupar dentro de una estructura
variables de diferente tipo.
Para declarar una estructura se utiliza la sintaxis siguiente:
struct campo_etiqueta{
tipo_miembro miembro1;
tipo_miembro miembro2;
...
tipo_miembro miembron;
};
Para acceder a los miembros de una estructura, se declara una variable al momento de definir la estructura.
Por ejemplo: en el siguiente código, se crea una variable llamada e s t u d i a n t e para luego poder acceder a
los miembros de la estructura p e r s o n a , a través de la variable e s t u d i a n t e .
struct persona{
char nombre[20];
char apellido[20];
float nota1;
float nota2;
float nota3;
}estudiante;
Vea que en el código anterior la estructura termina con ( ; ) pues corresponde a una instrucción de C++, ahora
si queremos acceder a la información de un estudiante tendríamos que utilizar el nombre de la variable tipo
estructura seguida de un punto y el nombre del campo de la estructura al cual hacemos referencia (.). Por
ejemplo:
Asi accede al miembro n o m b r e dentro de la variable estructura, para asignarle una cadena de caracteres
(“j u a n ”):
strcpy(estudiante.nombre ,”juan”);
// estudiante.nombre
Para asignar valor al campo nota1:
estudiante.nota1=10;//nuevamente se usa (.)
De igual forma si queremos operar cualquier dato de la estructura, utilizaremos el nombre de variable que
referencia a estructura y luego el nombre del dato, en este ej. a variable e s t u d i a n t e .
promedio=(estudiante.nota1 + estudiante.nota2 +estudiante.nota3)/3;
Arreglos de Estructuras
Se declaran como cualquier otro arreglo, es decir, se le asigna un total de elementos al momento de crear el
arreglo, por ej.:
struct persona{
___________________________________________________________________________________________
4
int edad;
char nombre[ ];
};
struct persona lista[10]; //10 variables tipo estructuras
lista[0].edad=1;
strcpy(lista[0].nombre,”Juan Perez”);
III. Requerimientos
Nº
1
2
3
Cantidad
1
1
1
Descripción
Compilador Dev-C++
Guía de Laboratorio #10 de Introducción a la Programación
Memoria USB
IV. Procedimiento
1. Preparar una carpeta denominada IPguia10proc_CARNET, en el cual se guardara cada uno de los cpp’s
del procedimiento y de los problemas a resolver.
Manejo de Cadenas de caracteres
1. El siguiente ejemplo (nombre archivo: Ejemplo1_cadenas.cpp) demuestra cómo usar los arreglos
bidimensionales de caracteres (char) para almacenar múltiples cadenas.
Problema:
Desarrolle una aplicación que permita registrar el nombre y las notas de los 3 periodos de N estudiantes de
Humanística I. Al finalizar el ingreso de datos, se muestra un informe académico final del curso, con el nombre
de c/estudiante, su promedio final y si aprobó o no (A o R).
#include <iostream>
using namespace std;
#include <iomanip>
#include <conio.h>
#include <stdlib.h>
#define tam1 4 //3 notas periodo y prom-final
main(){
int totalum; //total estudiantes del curso
int i,j,k; //contadores para ciclos y arreglos
___________________________________________________________________________________________
5
cout<<"\tPrograma de registro academico";
cout<<"\nEscriba total estudiantes del curso de Humanistica I: ";
cin>>totalum;
//define matrices segun tamaño brindado por usuario
char nombres[totalum][25]; //para (totalum) nombres de 25 caracteres
max
float notas[totalum][tam1]; //para 3 notas periodo y nota final
//recorre arreglo para guardar datos dados por usuario
i=0; //1er elemento de ambos arreglos
while(i<totalum){
cout<<endl<<endl<<"Digitar nombres de Estudiante "<<i+1<<": ";
/*CAPTURA UNA CADENA DE CARACTERES CON ESPACIOS*/
fflush(stdin);//limpia buffer entrada antes de invocar funcion getline
cin.getline (nombres[i],25);
for(k=0;k<3;k++){
cout<<endl<<"Ingrese nota de periodo "<<k+1<<" :\t";
cin>>notas[i][k];
}//fin for k
notas[i][3]=0;//asigna nota final prom de cero.
i++; //incremento contador i
}//fin while i
//calcula nota promedio de c/estudiante
i=0;
while(i<totalum){
//acumula en posicion notas[i][3] el porcentaje
//de c/nota de periodo
notas[i][3]+=notas[i][0]*0.3;
notas[i][3]+=notas[i][1]*0.35;
notas[i][3]+=notas[i][2]*0.35;
i++;//proximo estudiante
}//fin while i
system("cls");
cout.setf(ios::fixed);
cout<<"\nInforme academico final\n\n";
cout<<setw(62)<<setfill('_')<<"\n";
cout.setf(ios::left);
cout<<setw(3)<<"No."<<"|"<<setw(30)<<"NOMBRES"<<"|";
cout<<setw(4)<<"p1"<<"|"<<setw(4)<<"p2"<<"|"<<setw(4)<<
"p3"<<"|"<<setw(6)<<"final"<<"|"<<setw(3)<<"A/R"<<"|";
//recorre ambos arreglos para generar informe final
for(i=0;i<totalum;i++){
cout.setf(ios::left);
cout<<"\n"<<setw(3)<<i<<"|"<<setw(30)<<nombres[i]<<"|";
cout.precision(1);
cout.unsetf(ios::left);
for(k=0;k<tam1-1;k++)//presenta c/nota del estudiante
cout<<setw(4)<<notas[i][k]<<"|";
cout.precision(2);
cout<<setw(6)<<notas[i][3]<<"|";
//determina si aprobo o no el curso
___________________________________________________________________________________________
6
if(notas[i][3]>=6.0) cout<<setw(3)<<"A"<<"|";
else cout<<setw(3)<<"R"<<"|";
}//fin for i
getch();
} //fin main
2. Compilar la aplicación anterior y probarla con un total de 3 estudiantes.
3. El siguiente ejemplo (nombre archivo a crear: Ejemplo2_cadenas.cpp) demuestra cómo usar los
arreglos de caracteres (char) para el procesamiento de cadenas de caracteres (string).
Problema:
Solicitar a usuario una frase cualquiera, para que luego se le muestre en pantalla a la frase ingresada y detalle
el total de cada una de las letras que compone la frase.
El programa aceptara del usuario que presione exclusivamente cualquier letra (incluyendo la ‘ñ’), el carácter
espacio en blanco o la tecla Intro. Cualquier otra tecla será ignorada.
La tecla Intro permitirá ver los resultados y finalizar la aplicación.
#include<iostream>
using namespace std;
#include<conio.h>
main(){
//ENTRADAS
char tecla;//tecla presionada por usuario
//PROCESO
int i; //contador usos varios
//SALIDAS
/*teclas ASCII a ser tomadas en cuenta en conteo:
+caracter 'a'(97) a caracter 'z'(122)
+carácter ‘ñ’ (164)
+espacio en blanco ' ' (32)
Desde indice 0 (espacio en blanco) e indice 27 (letra ñ )
y de indice 1 (letra 'a') hasta indice 26 (letra 'z')
*/
int c[28];//contador de letras y espacios
//inicializa con cero a c/posicion de arreglo c
for(i=0;i<28;i++)
c[i]=0;//asigna conteo de cero letras a cada contador
cout<<"\tAnalizador de letras de una frase\n";
cout<<"Ingrese la frase a evaluar: ";
//lee la frase, letra por letra
do{
tecla=getch();//lee tecla pero sin mostrarla
___________________________________________________________________________________________
7
//clasifica valor ascii de tecla presionada
if(tecla>='a' && tecla<='z' ){
c[tecla-96]++;//cuenta letra entre 'a' - 'z'
cout<<tecla;
}else
if(tecla==' '){
c[0]++;//cuenta espacios en blanco
cout<<tecla;
}else
if(tecla==char(164)){ //caracter ñ
c[27]++;//cuenta caracter ñ
cout<<tecla;
}else
if(tecla==13)
break;//finaliza ciclo while
//caracter retorno carro (intro): 13
}while (true); //repite infinitamente cuerpo ciclo
//Muestra las estadisticas de frase digitada
cout<<"\n\nTotal palabras de la Frase: "<<c[0]+1;
cout<<"\n\nTotal de Letras utilizadas:";
for(i=1;i<27;i++)
if(c[i]>0)
cout<<"\n letra "<<char(i+96)<<" -> "<<c[i];
if(c[27]>0)
cout<<"\n letra "<<char(164)<<" -> "<<c[27];
getch();
}//fin main
Estructuras en C++
4. Digite el siguiente ejemplo. Ejemplo3_struct.cpp
Programa que administra información compuesta sobre productos de un supermercado por medio de un
arreglo de datos de tipo estructura (struct)
#include<iostream>
using namespace std;
#include<conio.h>
//estructura para almacenar info. de productos
struct Producto{
char nombre[18];
//a.alimento, b.limpieza, c.refresco, d.golosina
char tipo;
float precioc;
float preciov;
int existencia;
};//fin struct Producto
___________________________________________________________________________________________
8
main(){
int i,j;//contador usos varios
int totprod;//tot productos a ingresar
int cpro=0; //contador productos
char tiposprod[5][25]={
"alimento", "limpieza", "refresco", "golosina"
};
cout<<"Total productos a registrar??\t";
cin>>totprod;
//dimensiona arreglo productos
Producto produ[totprod];
cpro=0;
do{//registra datos de c/prod
cout<<"\n\nProducto "<<cpro+1<<":\n";
cout<<"\nnombre ??";
fflush(stdin);
cin.getline(produ[cpro].nombre,18);
cout<<"\nTipo de producto:\n";
for(i=0;i<4;i++){
cout<<char(97+i)<<"."<<tiposprod[i]<<"\t";
}//fin for i
cout<<"\n-> presione letra de tipo producto:";
produ[cpro].tipo=getche();
cout<<"\n\nDigite Precio($) compra y de Venta, y Existencia"<<
"\n(separados por un espacio c/u y presionar Enter al terminar):\n";
cin>>produ[cpro].precioc;
cin>>produ[cpro].preciov;
cin>>produ[cpro].existencia;
cpro++; //proximo producto
}while(cpro<totprod);//fin do-while cpro
//detalla listado productos registrados
//system("cls");
cout<<"\nLISTA PRODUCTOS\n";
j=0;
while(j<cpro){
cout<<"\n\n--> Producto "<<produ[j].nombre;
cout<<"\nTipo: "<<produ[j].tipo;
cout<<"\nExistencia: "<<produ[j].existencia;
cout<<"\nPrecio $ compra: "<<produ[j].precioc<<
" venta: "<<produ[j].preciov;
j+=1;
}//fin while j
getch();
}//fin main
5. Ejecute el programa anterior y analice como se acceden a los miembros de una estructura.
Observe cómo se comportan los 3 operadores cin continuos (que solicitan la existencia, precio venta y de
compra) cuando se escriben los valores a ingresar en una misma línea (separados por espacio ‘ ’)
___________________________________________________________________________________________
9
6. Digite el siguiente ejemplo. Ejemplo4_struct.cpp
Programa que administra información compuesta por medio de un arreglo de datos de tipo estructura (struct)
#include<iostream>
using namespace std;
#include<iomanip>
//en C++ una estructura representa un tipo de dato compuesto
struct Persona{
int Codigo;
char Nombre[30];
char Carrera[40];
int Edad;
};
main(){
int opc=0,i=0,j;
//se declarar un arreglo de variables (Estudiante) de tipo Persona
Persona Estudiante[3];
do { //genera un menu de opciones para el usuario
cout<<"\t *******DATOS DE PERSONAS********"<<endl;
cout<<"\n \t 1.Agregar Alumnos"<<endl;
cout<<"\n \t 2.Mostrar Alumnos"<<endl;
cout<<"\n \t 3.Salir"<<endl;
cout<<"\n \n Ingrese una de las tres opciones disponibles: ";
cin>>opc;
switch(opc){
case 1:
if(i==3){
cout<<"\nERROR SOLO SE PUEDEN CREAR 3 ALUMNOS \n";
break; //finaliza switch opc
}
cout<<"\ncorrelativo #: "<<i+1<<endl;
Estudiante[i].Codigo=i+1;//asigna correlativo
cout<<"\n Codigo --: "<<Estudiante[i].Codigo;
cout<<"\n Nombre---: ";
fflush(stdin); gets(Estudiante[i].Nombre);
cout<<"\n Carrera ---: ";
fflush(stdin); gets(Estudiante[i].Carrera);
cout<<"\n Edad ---: ";
cin>>Estudiante[i].Edad;
//incrementamos cantidad y lista de alumnos
i+=1;
break;
case 2:
cout<<"\nEstudiantes registrados:\n";
//coloca el encabezado
cout<<"\n"<<setw(7)<<"CODIGO"<<setw(18)<<"\tNOMBRE"<<
setw(16)<<"\tCARRERA"<<setw(10)<<"\tEDAD" <<endl;
___________________________________________________________________________________________
10
j=0;
cout.setf(ios::left);
while(j<i){
cout<<"\n\t"<<setw(5)<<Estudiante[j].Codigo<<"| "<<setw(20)<<
Estudiante[j].Nombre<<
"| "<<setw(15)<<Estudiante[j].Carrera;
cout<<"| "<<Estudiante[j].Edad;
j++;
}//fin ciclo while j
cout<<"\n";
break;
case 3:
cout<<"El programa finalizara \n ";
break;
default:
cout<<"\n La opcion no esta definida, intente nuevamente\n";
}//fin de switch
system("pause");
system("cls");
}while(opc!=3);//mantiene el lazo
}//fin main
7. Ejecute el programa anterior y analice como se acceden a los miembros de una estructura.
PROBLEMAS COMPLEMENTARIOS:
Elabore el código fuente de C++ que solucionen a cada uno de los problemas a continuación:
Problema1.cpp
Cree un programa que permita recibir el nombre completo de una persona (en minúscula), para luego
retornarle a usuario ese mismo nombre pero con sus letras iniciales en mayúsculas.
Por ej.
si ingresa el nombre i r e n e j a z m i n s a n d o v a l d e p i n e d a se mostrara como:
Irene Jazmin Sandoval De Pineda
Problema2.cpp
Crear un programa que permita almacenar la información sobre medicamentos para una farmacia.
Una vez ingresados los datos, los registros de medicamentos se ordenaran (y presentaran al usuario) por tipo
de medicamentos (jarabe, inyección, pastillas y colirio).
___________________________________________________________________________________________
11
V. Análisis de resultados
Crear el siguiente ejercicio:
Crear una estructura llamada contactoEmail que tenga las siguientes características:
Nombres Completo
Sexo
Edad
Teléfono
Email
nacionalidad
El programa debe constar de un menú que permita:
a)
b)
c)
d)
Agregar un contacto
Eliminar un contacto
Mostrar listado general de contactos registrados hasta ese momento.
Mostrar listado de contactos existentes, ordenado por servidor de correo de las cuentas (gmail.com,
yahoo.com, Hotmail.es, etc.)
El programa debe mantenerse en ejecución continuamente hasta que usuario indique que desea salir del
mismo.
___________________________________________________________________________________________
12
Descargar