UNED: FUNDAMENTOS DE PROGRAMACIÓN: TERCERA PRÁCTICA
Enunciado:
Se trata de realizar un programa que muestre por pantalla la hoja del calendario de cualquier mes y año comprendido entre los años 1601 y 3000. El problema debe pedir el mes y el año sólo una vez para cada ejecución.
Se debe tener en cuenta que el día 1 de enero de 1601 fue lunes y que son años bisiestos los múltilplos de 4 excepto los que son múltiplos de 100 y que no son también múltiplos de 400.
Código:
#include <stdio.h>
/* Nuevo tipo enumerado para manejar los días de la semana. Lunes == 0, domingo == 6 */
typedef enum TipoDia {lunes, martes, miercoles, jueves, viernes, sabado, domingo};
/* Variables globales a usar en el programa */
int Mes, Anno;
/* Función bool (true o false) para determinar si un año es o no bisiesto */
bool EsBisiesto (int Anno) {
if ((Anno % 400 == 0)) {
return true;
} else if ((Anno % 4 == 0) && (Anno % 100 != 0)) {
return true;
} else {
return false;
}
}
/* Función para calcular el día de la semana con la que comienza un mes de un año */
TipoDia DiaDeLaSemana (int Mes, int Anno) {
int cuentaTotal, cuentaAnnos, cuentaMeses, diasPorMes, diasAnno, diaSemana;
/* Calcula el número de días transcurridos desde el (1/1/1601) hasta el (1/1/año a calcular) */
cuentaAnnos = 0;
for (int k = 1601; k <= Anno-1; k++) {
if (EsBisiesto (k)) {
diasAnno = 366;
} else {
diasAnno = 365;
}
cuentaAnnos = cuentaAnnos + diasAnno;
}
/* Calcula el número de días transcurridos desde el (1/1/año a calcular) hasta el (1/mes a calcular/año a calcular) */
cuentaMeses = 0;
for (int k = 1; k <= Mes-1; k++) {
if ((k == 1)|| (k == 3) || (k == 5) || (k == 7) || (k == 8) || (k == 10)) {
diasPorMes = 31;
} else if (k == 2) {
if (EsBisiesto (Anno)) {
diasPorMes = 29;
} else {
diasPorMes = 28;
}
} else {
diasPorMes = 30;
}
cuentaMeses = cuentaMeses + diasPorMes;
}
cuentaTotal = cuentaAnnos + cuentaMeses; /* Calcula el número de días transcurridos desde el (1/1/1601) hasta el (1/mes a calcular/año a calcular) */
diaSemana = cuentaTotal % 7; /* Si == 0 es lunes, == 1 es martes, etc... */
return TipoDia (diaSemana);
}
/* Procedimiento para imprimir el resultado */
void ImprimirCalendario (int Mes, int Anno) {
int diasPorMes, diaDelMes, numFilas;
const int numColumnas = 7;
/* Número de días del mes a calcular*/
if ((Mes == 1) || (Mes == 3) || (Mes == 5) || (Mes == 7) || (Mes == 8) || (Mes == 10) || (Mes == 12)) {
diasPorMes = 31;
} else if (Mes == 2) {
if (EsBisiesto (Anno)) {
diasPorMes = 29;
} else {
diasPorMes = 28;
}
} else {
diasPorMes = 30;
}
/* Número de filas del calendario, 4, 5 o 6 */
if ((diasPorMes == 31) && (DiaDeLaSemana (Mes, Anno) >= 5) ) {
numFilas = 6;
} else if ((diasPorMes == 30) && (DiaDeLaSemana (Mes, Anno) == 6) ) {
numFilas = 6;
} else if ((diasPorMes == 28) && (DiaDeLaSemana (Mes, Anno) == 0) ) {
numFilas = 4;
} else {
numFilas = 5;
}
/* Impresión del nomnbre del mes */
if (Mes == 1) {
printf( "ENERO%22d\n", Anno );
} else if (Mes == 2) {
printf ( "FEBRERO%20d\n", Anno );
} else if (Mes == 3) {
printf ( "MARZO%22d\n", Anno );
} else if (Mes == 4) {
printf ( "ABRIL%22d\n", Anno );
} else if (Mes == 5) {
printf ( "MAYO%23d\n", Anno );
} else if (Mes == 6) {
printf ( "JUNIO%22d\n", Anno );
} else if (Mes == 7) {
printf ( "JULIO%22d\n", Anno );
} else if (Mes == 8) {
printf ( "AGOSTO%21d\n", Anno );
} else if (Mes == 9) {
printf ( "SEPTIEMBRE%17d\n", Anno );
} else if (Mes == 10) {
printf ( "OCTUBRE%20d\n", Anno );
} else if (Mes == 11) {
printf ( "NOVIEMBRE%18d\n", Anno );
} else {
printf ( "DICIEMBRE%18d\n", Anno );
}
printf ( "===========================\n" );
printf ( "LU MA MI JU VI | SA DO\n" );
printf ( "===========================\n" );
diaDelMes = 1;
/* Primera fila del mes */
for (int j = 0; j < numColumnas; j++) {
if (j < DiaDeLaSemana (Mes, Anno)) {
if ((j == 0) || (j == 5)) {
printf ( " ." );
} else if (j == 4) {
printf ( " . | " );
} else {
printf ( " .");
}
} else {
if ((j == 0) || (j == 5)) {
printf ( "%2d", diaDelMes - DiaDeLaSemana (Mes, Anno) );
} else if (j == 4) {
printf ( " %2d | ", diaDelMes - DiaDeLaSemana (Mes, Anno) );
} else {
printf (" %2d", diaDelMes - DiaDeLaSemana (Mes, Anno) );
}
}
diaDelMes = diaDelMes + 1;
}
printf (" \n");
/* Una iteración por número de filas centrales */
for (int i = 0; i < numFilas-2; i++) {
for (int j = 0; j < numColumnas; j++) {
if ((j == 0) || (j == 5)) {
printf ( "%2d", diaDelMes - DiaDeLaSemana (Mes, Anno) );
} else if (j == 4) {
printf ( " %2d | ", diaDelMes - DiaDeLaSemana (Mes, Anno) );
} else {
printf (" %2d", diaDelMes - DiaDeLaSemana (Mes, Anno) );
}
diaDelMes = diaDelMes + 1;
}
printf ( "\n" );
}
/* Última fila del mes */
for (int j = 0; j < numColumnas; j++) {
if ((diaDelMes - DiaDeLaSemana (Mes, Anno)) <= diasPorMes ) {
if ((j == 0) || (j == 5)) {
printf ( "%2d", diaDelMes - DiaDeLaSemana (Mes, Anno) );
} else if (j == 4) {
printf ( " %2d | ",diaDelMes - DiaDeLaSemana (Mes, Anno) );
} else {
printf (" %2d", diaDelMes - DiaDeLaSemana (Mes, Anno) );
}
} else {
if ((j == 0) || (j == 5)){
printf ( " ." );
} else if (j == 4) {
printf ( " . | " );
} else {
printf ( " .");
}
}
diaDelMes = diaDelMes + 1;
}
}
/* Programa Principal */
int main () {
/* Entrada de los dos datos que necesitamos: mes y año */
printf( "¿Mes (1..12)?" );
scanf( "%d", &Mes );
printf( "¿Año (1601..3000)?" );
scanf( "%d", &Anno );
printf( "\n" );
if (Mes < 1 || Mes > 12) {
return 0;
} else if (Anno < 1601 || Anno > 3000) {
return 0;
} else {
ImprimirCalendario (Mes, Anno);
}
}
Enlace al archivo cpp: http://www.lacoctelera.com/myfiles/arquitrasto/practica_3_publica.rar
Jose A dijo
¿Vas a poner la cuarta práctica? Lo llevo intentando días y no soy capaz, estoy muy bloqueado, a pesar de haber hecho bastante cómodamente las anteriores. Al menos alguna referencia para ver como hacerlo. Un saludo.
8 Enero 2012 | 08:26 PM