Skip to content
This repository was archived by the owner on Mar 12, 2021. It is now read-only.

Commit 53555cd

Browse files
committed
Commit inicial
0 parents  commit 53555cd

11 files changed

+1939
-0
lines changed

.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*.sln
2+
*.vcxproj
3+
*.vcxproj.user
4+
.vs/
5+
.vscode/
6+
.git/

alumnos.cpp

+352
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,352 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
#include "alumnos.h"
5+
#include "functions.h"
6+
#include <locale.h>
7+
8+
/*
9+
La documentacion acerca de lo que hace cada funcion esta en alumnos.h
10+
Aqui se explica instruccion por instruccion lo que hace cada una
11+
*/
12+
13+
Alumno *Al = NULL;
14+
15+
16+
Fecha crearFecha() {
17+
// asumimos que la fecha es invalida inicialmente
18+
int esValida = 0;
19+
// fecha a devolver
20+
Fecha fecha;
21+
// mientras sea invalida la fecha, volvemos a llenar los datos (Posible optimizacion seria solamente pedir el dato erroneo)
22+
while( ! esValida ) {
23+
// solicitamos el dia (1-31)
24+
printf("\tDía: \n");
25+
scanf( "%hu", &(fecha.dia) );
26+
// solicitamos el mes (1-12)
27+
printf("\tMes: \n");
28+
scanf( "%hu", &(fecha.mes) );
29+
// solicitamos el año (mayor a 1970)
30+
printf("\tAño: \n");
31+
scanf( "%hu", &(fecha.ano) );
32+
33+
/*
34+
Validaciones. Si una falla, las demas tienen que fallar
35+
Si bien se podria hacer en una instruccion, siento que asi es mas facil de leer, asi como mas ordenado
36+
*/
37+
esValida = fecha.ano > 1970;
38+
esValida = esValida && (fecha.mes > 0 && fecha.mes <= 12);
39+
esValida = esValida && (fecha.dia > 0 && fecha.dia <= 31);
40+
41+
// si es invalida, hay que hacerselo saber al usuario
42+
if ( ! esValida )
43+
printf("Formato de fecha incorrecto. Por favor vuelva a ingresar los datos\n");
44+
}
45+
46+
// regresamos
47+
return fecha;
48+
}
49+
50+
void printAlumno(Alumno *A, int detalle) {
51+
if (!A) return; // solamente actuamos si el alumno no es NULL
52+
printf("Información del alumno: %s %s\n", A->nombre, A->apellido);
53+
printf("\tNombre completo: %s %s\n", A->nombre, A->apellido);
54+
printf("\tCédula: %i\n", A->cedula);
55+
if ( detalle ) {
56+
printf("\tFecha Nacimiento: %hhu/%hhu/%hhu\n", A->fechaNac.dia, A->fechaNac.mes, A->fechaNac.ano);
57+
printf("\tTeléfono: %s\n", A->telefono);
58+
printf("\tCorreo: %s\n", A->correo);
59+
printf("\tDirección: %s\n", A->direccion);
60+
}
61+
}
62+
63+
void printListaAlumno(Alumno *A, int detalle) {
64+
// solamente actuamos si la lista no esta vacia
65+
if (!A) {
66+
printf("\tLista vacía\n");
67+
return;
68+
}
69+
printf("----------------------------\n\n");
70+
// mostramos la informacion de este alumno como nos la planteen
71+
printAlumno(A, detalle);
72+
// si tenemos mas alumnos, llamamos recursivamente con el siguiente, caso contrario, cerramos la tablita y salimos de la pila
73+
if (A->prox) printListaAlumno(A->prox, detalle);
74+
else printf("----------------------------\n");
75+
}
76+
77+
int cantidadAlumnos( Alumno *A ) {
78+
// si el alumno es nulo, regresamos 0, sino aumentamos uno a la cuenta
79+
return A ? cantidadAlumnos(A->prox) +1 : 0;
80+
}
81+
82+
void insertarAlumno(Alumno **P, Alumno *A) {
83+
// si no hay Cabeza, se asigna al A alumno y regresamos
84+
if (!*P) {
85+
*P = A;
86+
return;
87+
}
88+
89+
// si el primer elemento de la cabeza cumple con las condiciones, reasignamos la cabeza y regresamos
90+
if ((*P)->cedula > A->cedula) {
91+
A->prox = *P;
92+
*P = A;
93+
return;
94+
}
95+
96+
// empezamos a iterar
97+
Alumno *t = *P;
98+
while (t && t->prox) {
99+
if (t->prox->cedula > A->cedula) {
100+
// si encontramos uno mayor que la cedula, lo insertamos
101+
A->prox = t->prox;
102+
t->prox = A;
103+
return;
104+
}
105+
else
106+
t = t->prox;
107+
}
108+
109+
// si no hemos insertado hasta este punto, es el ultimo.
110+
t->prox = A;
111+
}
112+
113+
Alumno *obtenerAlumnoPorCedula(Alumno *A, int cedula) {
114+
// Como los alumnos deben estar insertados por cedula (menor-mayor), podemos salir si no hay elemento actual o si la cédula actual es mayor a la cédula a buscar
115+
if ( ( ! A ) || A->cedula > cedula ) return NULL;
116+
117+
// si no regresamos null, entonces comparemos la cedula. Si hay coincidencia regresamos el alumno, caso contrario vamos con el siguiente
118+
return A->cedula == cedula ? A : obtenerAlumnoPorCedula( A->prox, cedula );
119+
}
120+
121+
122+
Alumno *obtenerAlumnosPorNombre(Alumno *P, char *nombre ) {
123+
// declaramos la lista que devolveremos al final
124+
Alumno *coincidencias = NULL, *A = P;
125+
nombre = minusculas( nombre );
126+
// iteramos sobre la lista de alumnos dada
127+
while ( A ) {
128+
// comparamos el nombre en minúsculas del alumno actual con el nombre en minúsculas a buscar
129+
// si está, lo insertamos en la lista de coincidencias
130+
if ( strstr( minusculas( A->nombre ), nombre ) ) insertarAlumno( &coincidencias, extraerAlumno(P, A->cedula) );
131+
// vamos al siguiente alumno de la lista
132+
A = A->prox;
133+
}
134+
135+
// regresamos lo que sea que hayamos encontrado
136+
return coincidencias;
137+
}
138+
139+
Alumno *crearAlumno(void) {
140+
// declaramos el nuevo alumno a insertar, y un auxiliar para saber si el alumno existe
141+
Alumno *A = new Alumno, *existe = NULL;
142+
143+
miflush(); // limpiamos el buffer de entrada
144+
145+
// solicitamos el nombre del alumno
146+
printf( "Nombre del alumno: " );
147+
gets_s( A->nombre );
148+
149+
// solicitamos el apellido del alumno
150+
printf( "Apellido del alumno: " );
151+
gets_s( A->apellido );
152+
153+
// solicitamos la cedula del alumno hasta que esta sea una cedula unica (No este en el sistema)
154+
do {
155+
printf( "Cédula de identidad del alumno: " );
156+
scanf( "%i", &(A->cedula) );
157+
existe = obtenerAlumnoPorCedula( Al, A->cedula );
158+
if ( existe )
159+
printf("El alumno con la cédula \"%i\" ya existe, pertence a %s\n Por favor ingrese otro número de cédula\n", existe->cedula, existe->nombre);
160+
} while( existe );
161+
162+
miflush(); // despues de una llamada a scanf, hay que limpiar el buffer
163+
164+
// solicitamos la direccion del alumno
165+
printf( "Dirección: " );
166+
gets_s( A->direccion );
167+
168+
// solicitamos el numero telefonico del alumno
169+
printf( "Teléfono: " );
170+
gets_s( A->telefono );
171+
172+
// solicitamos los datos de la fecha de nacimiento del alumno
173+
printf( "Fecha Nacimiento: " );
174+
A->fechaNac = crearFecha();
175+
176+
miflush(); // despues de una llamada a scanf, hay que limpiar el buffer
177+
178+
// solicitamos el correo electronico del alumno
179+
printf( "Correo Electrónico: " );
180+
gets_s( A->correo );
181+
182+
// inicializamos el proximo elemento de este alumno como nulo
183+
A->prox = NULL;
184+
185+
// devolvemos
186+
return A;
187+
}
188+
189+
void modificarAlumno(Alumno **P) {
190+
// nada mas actuamos si no tenemos un puntero a nulo
191+
if (*P) {
192+
int opt = -1, cedula = -1;
193+
Alumno *existe = NULL;
194+
195+
// salimos cuando la opcion sea 0
196+
do {
197+
// mostramos el encabezado
198+
impCabezado();
199+
printAlumno(*P);
200+
impMenu(
201+
"Estas son las opciones disponibles para los alumnos.\nMarque la opción de acuerdo a la operación que desea realizar",
202+
6,
203+
"Editar número de cédula",
204+
"Editar el nombre del alumno",
205+
"Editar la dirección del alumno",
206+
"Editar número de teléfono",
207+
"Editar fecha de nacimiento",
208+
"Editar correo electrónico"
209+
);
210+
scanf("%i", &opt);
211+
miflush();
212+
switch ( opt ) {
213+
case 0: break;
214+
case 1:
215+
do {
216+
printf("Introduzca el nuevo número de cédula para %s. Actual: %d: ", (*P)->nombre, (*P)->cedula);
217+
scanf("%i", &(cedula));
218+
if (existe = obtenerAlumnoPorCedula(Al, cedula))
219+
printf("Error al cambiar el numero de cédula: Un alumno con esa cédula ya existe en el sistema: %s %s\n", existe->nombre, existe->apellido);
220+
} while ( existe );
221+
printf("Cédula cambiada con éxito\n");
222+
system("pause");
223+
break;
224+
case 2:
225+
printf("Introduzca un nuevo nombre para %s: ", (*P)->nombre);
226+
gets_s( (*P)->nombre );
227+
printf("Introduzca un nuevo apellido para %s. Actual: %s: ", (*P)->nombre, (*P)->apellido);
228+
gets_s( (*P)->apellido );
229+
printf("Nombres y apellido cambiados con éxito\n");
230+
system("pause");
231+
break;
232+
case 3:
233+
printf("Introduzca una nueva dirección para %s. Actual: %s: ", (*P)->nombre, (*P)->direccion);
234+
gets_s( (*P)->direccion );
235+
printf("Dirección cambiada con éxito\n");
236+
system("pause");
237+
break;
238+
case 4:
239+
printf("Introduzca un nuevo número de teléfono para %s. Actual: %s: ", (*P)->nombre, (*P)->telefono);
240+
gets_s( (*P)->telefono );
241+
printf("Número de teléfono cambiado con éxito\n");
242+
system("pause");
243+
break;
244+
case 5:
245+
printf("Introduzca una nueva fecha de nacimiento para %s. Actual: %hi/%hi/%hi: ", (*P)->nombre, (*P)->fechaNac.ano, (*P)->fechaNac.mes, (*P)->fechaNac.dia);
246+
(*P)->fechaNac = crearFecha();
247+
printf("Fecha de nacimiento cambiada con éxito\n");
248+
system("pause");
249+
break;
250+
case 6:
251+
printf("Introduzca un nuevo correo electrónico para %s. Actual: %s: ", (*P)->nombre, (*P)->correo);
252+
gets_s( (*P)->correo );
253+
printf("Correo electrónico cambiado con éxito\n");
254+
system("pause");
255+
break;
256+
default:
257+
printf("Opción no reconocida. Vuelva a intentar\n");
258+
}
259+
} while ( opt );
260+
}
261+
}
262+
263+
void elimAlumno(Alumno **P, int cedula) {
264+
if (! *P) return; // regresamos si el listado esta vacio
265+
if ((*P)->cedula > cedula) return; // como estan ordenados, podemos salir si la cedula a buscar es mas pequeña que la primera
266+
Alumno *del; // declaramos un auxiliar de eliminacion
267+
if ((*P)->cedula == cedula) {
268+
// si la cedula coincide con el primer elemento, tenemos que eliminar la cabeza
269+
del = *P;
270+
*P = (*P)->prox;
271+
if (impSiNo("Seguro que desea eliminar este alumno?"))
272+
delete del;
273+
return;
274+
}
275+
276+
// ayudante para iterar
277+
Alumno *alumno = *P;
278+
// iteramos hasta el ultimo elemento
279+
while ( alumno && alumno->prox ) {
280+
// podemos salir temprano si la cedula del proximo es mayor que la cedula a buscar
281+
if (alumno->prox->cedula > cedula) break;
282+
283+
if (alumno->prox->cedula == cedula) {
284+
// si la cedula del proximo en la lista coincide, entonces tenemos que eliminarlo
285+
del = alumno->prox;
286+
alumno->prox = del->prox;
287+
if (impSiNo("Seguro que desea eliminar este alumno?"))
288+
delete del;
289+
return;
290+
}
291+
292+
alumno = alumno->prox;
293+
}
294+
}
295+
296+
void consultarAlumno(Alumno **P, int cedula) {
297+
Alumno *alumno = obtenerAlumnoPorCedula(*P, cedula);
298+
if (alumno)
299+
printAlumno(alumno);
300+
else
301+
printf( "No se encontró a ningún alumno con la cédula '%i'\n", cedula );
302+
}
303+
304+
void vaciarListaAlumnos(Alumno **P) {
305+
if (*P) {
306+
vaciarListaAlumnos(&((*P)->prox));
307+
delete (*P);
308+
}
309+
}
310+
311+
void extraerAlumnosDesdeArchivo(Alumno **P, FILE *f) {
312+
// reservamos memoria
313+
Alumno *A = new Alumno;
314+
// leemos registro
315+
fread(A, sizeof Alumno, 1, f);
316+
// comprobamos que no sea fin de archivo
317+
if ( ! feof(f) ) {
318+
// volvemos el siguiente nulo
319+
A->prox = NULL;
320+
// insertamos
321+
insertarAlumno(P, A);
322+
// llamamos recursivamente
323+
extraerAlumnosDesdeArchivo(P, f);
324+
}
325+
else delete A; // si llegamos a fin de archivo, liberemos la memoria (no lo hacemos siempre porque la memoria declarada aqui fue insertada
326+
}
327+
328+
Alumno *extraerAlumno(Alumno *A, int cedula) {
329+
// Alumno a extraer de la lista
330+
Alumno *objetivo = obtenerAlumnoPorCedula(A, cedula),
331+
// Alumno a devolver
332+
*extraido = new Alumno;
333+
334+
// si no obtuvimos nada, limpiamos la memoria reservada y regresamos nulo
335+
if ( ! objetivo ) {
336+
delete extraido;
337+
return NULL;
338+
}
339+
340+
// copiamos todos los campos, y nulificamos el puntero a proximo
341+
strcpy_s(extraido->nombre, sizeof(objetivo->nombre), objetivo->nombre);
342+
strcpy_s(extraido->apellido, sizeof(objetivo->apellido), objetivo->apellido);
343+
strcpy_s(extraido->direccion, sizeof(objetivo->direccion), objetivo->direccion);
344+
strcpy_s(extraido->telefono, sizeof(objetivo->telefono), objetivo->telefono);
345+
strcpy_s(extraido->correo, sizeof(objetivo->correo), objetivo->correo);
346+
extraido->prox = NULL;
347+
extraido->cedula = objetivo->cedula;
348+
extraido->fechaNac = objetivo->fechaNac;
349+
350+
// regresamos
351+
return extraido;
352+
}

0 commit comments

Comments
 (0)