2010-01-12 8 views
5

estoy atascado en el siguiente problema de mi clase de programación C:año de entrada, entonces el calendario de impresión

escribir un programa que pide al usuario que introduzca un año, y luego da salida al calendario (para todo el año) .

No tengo idea de cómo abordar este problema. Normalmente puedo comenzar mis problemas de tarea (este es un problema de desafío opcional), pero estoy realmente perdido. Hemos trabajado a través de los capítulos 1-10 de Deitel & Deitel (bucles, matrices, punteros, E/S, etc.), pero no sé cómo abordar esto en absoluto. Cualquier sugerencia o sugerencia sería apreciada.

+1

Si usted puede hacer que el programa imprime la primera semana de enero, tendrá el programa 90% hecho. –

+0

¿Cómo lo haría comenzar el mes en un día en particular? –

Respuesta

0

Un buen comienzo puede ser la hora local (3) y mktime (3) funciones. Alternativamente, puede implementar la aritmética de fecha relevante desde cero. Luego, simplemente, genere la primera línea del calendario (encuentre el día de la semana que corresponde al 1 de enero, luego imprima en el lugar correcto, seguido por el resto de la semana), luego imprima todas menos las últimas líneas, luego imprima la última línea.

Dependiendo de si desea un calendario paginado por mes o no, esto PUEDE realizarse mejor cada mes en lugar de por año.

3

En general, cuando tiene un gran problema como este, quiere descomponerlo en pequeños problemas que son más fáciles de resolver.

Aquí hay un pequeño problema posible para empezar: si sabe cuántos días hay en un mes y en qué día de la semana cae el primero del mes, ¿podría generar un calendario para ese mes?

1

Lo más difícil es determinar qué día de la semana comienza el año.

http://en.wikipedia.org/wiki/Calculating_the_day_of_the_week

Pero incluso sin el conocimiento de que, cuando implementó por primera vez de esto, he usado una fecha de referencia (por ejemplo, se sabe que hoy en día 11 de enero, 2010 es un lunes) y contados días a partir de ahí. (Hemos de tener en cuenta que los años bisiestos tienen un día extra, y que los años bisiestos son cada 4 años, excepto cada 100 años, excepto cada 400 años.)

http://en.wikipedia.org/wiki/Leap_year

4

Podría ayudar a entender las matemáticas de la calendario. Si el fabuloso libro Calendrical Calculations no está en la biblioteca de su universidad, pueden obtener una reimpresión del artículo de los mismos autores en Software — Práctica & Experiencia. Y pídele a tu profesor que solicite el libro para la biblioteca.

0

Bueno, primero descubra la parte algorítmica de su problema: dado un año, encuentre qué día es el 1 de enero.

Después de esto, solo tenga en cuenta el número de días en cada mes (guárdelo en una matriz, digamos num_days[]), y la nota el número de meses en un año y una serie de cadenas para los meses.

Por ej. el ciclo más externo itera durante los meses. Diga, itere for(i=0;i<NumMonths;++i). Luego, para cada mes, imprima la cadena, p. month[i], luego una nueva línea.

Luego, con pestañas simples, imprima Sun Mon Tue ..., y otra nueva línea.

Luego, utilizando el día 1 de enero corresponde (llámelo FirstDay), inserte espacios y comience ese día. Siga imprimiendo las fechas y saltos hasta que llegue al max_month[i] que es 31 (para enero). Almacene el nombre del día del último día del mes anterior y simplemente reitere tratar ese día como FirstDay.

0

Necesita un par de piezas para comenzar. Primero, necesita una fórmula que calcule el día de la semana para el 1 de enero del año que se ingrese. También necesitará una fórmula para determinar si el año es bisiesto. Ambas fórmulas se encuentran fácilmente con una simple búsqueda en Google. El tercer elemento que necesita es una matriz simple que contiene el número de días en cada uno de los 12 meses para un año no bisiesto.

Una vez que tenga estas cosas, es trivial determinar el día de la semana para cada mes del año. Asegúrese de dar cuenta del 29 de febrero en un año bisiesto. A partir de ahí, solo necesita crear una función que imprima el calendario mensual en un formato similar al calendario que cuelga en la pared. Primero dibuje el diseño deseado en papel y utilícelo como plantilla para crear las declaraciones de formato apropiadas.

0

Podría verificar el algoritmo doomsday. Esto le daría cierta certeza de que "los días del juicio final" como el 31 de enero es un día del juicio final, para el año 2008, que era un sábado. Puede trabajar contraseñas desde allí

+0

Esto es excesivo para un problema de tarea como este. – jason

1

¿Este código califica? :-)

char command[]="cal 2010"; 
sprintf(command,"cal %d",argv[1]); 
system(command); 

Asume una máquina Unix con cal en el camino.

0

Básicamente, existen dos enfoques:

  1. La manera fácil/pragmática: resolver la tarea, y olvidarse de todo lo demás. Aquí puede consultar la documentación del mktime() (encontrará un ejemplo basado en mktime a continuación).

  2. La manera científica/de ingeniería: ¡aprenda a saber cómo funciona! Puede comenzar en el great wikipedia article about the gregorian calendar. Léelo, entiéndelo y escriba el código que implementa los algoritmos subyacentes (que son conocidos, no hay ciencia espacial, es posible). Esto mejorará mucho sus habilidades (de hecho, realmente debería hacer tal cosa, tal vez no el calendario sino otro tema, le dará un gran salto en la comprensión de todo cosas).

Ahora, un código pragmático para empezar. mktime() tiene una gran característica: conoce los detalles del calendario y acepta, por ejemplo, una fecha "2010-01-60" y la convertirá al 29 de febrero de 2010. Pero esto solo funcionará para fechas posteriores a 1970. No funcionará para fechas anteriores (aunque no estoy 100% seguro, pero no debería) t funciona, porque el tiempo de Unix comienza el 1 de enero de 1970, pero intente con otras fechas, tal vez mktime() no está restringido a tiempo Unix).

pseudo-código, esta opción se imprime cada día en una sola línea (AAAA-MM-DD):

void print_cal(int year) { 
    static char weekdays[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; 
    struct tm tm; 
    for(int day=0; day<365; ++day) { 
     memset(&tm, 0, sizeof(tm)); 
     tm.tm_year = year - 1900; 
     tm.tm_mday = day; 
     mktime(&tm); // modifies tm 

     printf("%04d-%02d-%02d, %s\n", tm.tm_year, tm.tm_mon+1, tm.tm_mday, weekdays[tm.tm_wday]); 
    } 
} 

Este código hace caso omiso de los años bisiestos. ¡Todavía tiene que ajustarlo para que sea correcto para los años bisiestos! Además, el resultado aún no es muy bonito, solo una línea por día.

EDITAR: producción agregada de días laborables.

Cuestiones relacionadas