snp-lab-code/P02_Funktionen_Datentyp_enum/P2_aufgabe2.c

265 lines
6.2 KiB
C

/* ----------------------------------------------------------------------------
* -- _____ ______ _____ -
* -- |_ _| | ____|/ ____| -
* -- | | _ __ | |__ | (___ Institute of Embedded Systems -
* -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur -
* -- _| |_| | | | |____ ____) | (University of Applied Sciences) -
* -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland -
* ----------------------------------------------------------------------------
*/
/**
* @file
* @brief Lab P02 weekday
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
// *** TASK1: typedef enum types for month_t (Jan=1,...Dec} ***
// BEGIN-STUDENTS-TO-ADD-CODE
typedef enum {Jan=1, Feb, Mar, Apr, May, June, July, Aug, Sept, Oct, Nov, Dec} month_t;
// END-STUDENTS-TO-ADD-CODE
// *** TASK1: typedef struct for date_t ***
// BEGIN-STUDENTS-TO-ADD-CODE
typedef struct {int year, month, day;} date_t;
// END-STUDENTS-TO-ADD-CODE
// *** TASK2: typedef enum weekday_t (Sun=0, Mon, ...Sat) ***
// BEGIN-STUDENTS-TO-ADD-CODE
typedef enum {Sun=0, Mon, Tue, Wed, Thu, Fri, Sat} weekday_t;
// END-STUDENTS-TO-ADD-CODE
/**
* @brief TASK1: Checks if the given date is a leap year.
* @returns 0 = is not leap year, 1 = is leap year
*/
// BEGIN-STUDENTS-TO-ADD-CODE
int is_leap_year(date_t date){
int ergebnis;
if(date.year % 400 == 0){
ergebnis = 1;
}
else if (date.year % 100 == 0){
ergebnis = 0;
}
else if(date.year % 4 == 0){
ergebnis = 1;
}
else {
ergebnis = 0;
}
return ergebnis;
}
// END-STUDENTS-TO-ADD-CODE
/**
* @brief TASK1: Calculates the length of the month given by the data parameter
* @returns 28, 29, 30, 31 if a valid month, else 0
*/
// BEGIN-STUDENTS-TO-ADD-CODE
int get_month_length(date_t date){
int ergebnis = 0;
switch (date.month) {
case Jan:
ergebnis = 31;
break;
case Feb:
if(is_leap_year(date)){
ergebnis = 29;
}
else {
ergebnis = 28;
}
break;
case Mar:
ergebnis = 31;
break;
case Apr:
ergebnis = 30;
break;
case May:
ergebnis = 31;
break;
case June:
ergebnis = 30;
break;
case July:
ergebnis = 31;
break;
case Aug:
ergebnis = 31;
break;
case Sept:
ergebnis = 30;
break;
case Oct:
ergebnis = 31;
break;
case Nov:
ergebnis = 30;
break;
case Dec:
ergebnis = 31;
break;
}
return ergebnis;
}
// END-STUDENTS-TO-ADD-CODE
/**
* @brief TASK1: Checks if the given date is in the gregorian date range
* @returns 0 = no, 1 = yes
*/
// BEGIN-STUDENTS-TO-ADD-CODE
int is_gregorian_date(date_t date) {
int ergebnis = 1;
if((date.year == 1582 && date.month <= Oct && date.day < 15) || date.year < 1582 || (date.year > 9999)){
return 0;
}
else {
return 1;
}
}
// END-STUDENTS-TO-ADD-CODE
/**
* @brief TASK1: Checks if the given date is a valid date.
* @returns 0 = is not valid date, 1 = is valid date
*/
// BEGIN-STUDENTS-TO-ADD-CODE
int is_valid_date(date_t date) {
int ergebnis = 1;
int ml = get_month_length(date);
if((int)ml < (int)date.day ){//|| date.month < 1 || date.month > 12 || is_gregorian_date == 0){
return 0;
}
else {
printf("Länge Monat: %d\n", get_month_length(date));
printf("Länge Monat: %d\n", ml);
printf("Tag: %d\n", date.day);
printf("Monat: %d\n", date.month);
printf("Jahr: %d\n", date.year);
return 1;
}
}
// END-STUDENTS-TO-ADD-CODE
/**
* @brief TASK2: calculated from a valid date the weekday
* @returns returns a weekday in the range Sun...Sat
*/
// BEGIN-STUDENTS-TO-ADD-CODE
weekday_t calculate_weekday(date_t date) {
int m = 1 + (date.month + 9) % 12;
int a;
if(date.month < Mar){
a = date.year - 1;
}
else {
a = date.year;
}
int y = a % 100;
int c = a / 100;
weekday_t weekday = ((date.day + (13 * m - 1) / 5 + y + y / 4 + c / 4 - 2 * c) % 7 + 7) % 7;
return weekday;
}
// END-STUDENTS-TO-ADD-CODE
/**
* @brief TASK2: print weekday as 3-letter abreviated English day name
*/
// BEGIN-STUDENTS-TO-ADD-CODE
void print_weekday(weekday_t day) {
int ergebnis = 0;
switch (day) {
case Sun:
printf("Sun");
break;
case Mon:
printf("Mon");
break;
case Tue:
printf("Tue");
break;
case Wed:
printf("Wed");
break;
case Thu:
printf("Thu");
break;
case Fri:
printf("Fri");
break;
case Sat:
printf("Sat");
break;
default:
assert(!"day is out-of-range");
break;
}
}
// END-STUDENTS-TO-ADD-CODE
/**
* @brief main function
* @param argc [in] number of entries in argv
* @param argv [in] program name plus command line arguments
* @returns returns success if valid date is given, failure otherwise
*/
int main(int argc, const char *argv[])
{
// TASK1: parse the mandatory argument into a date_t variable and check if the date is valid
// BEGIN-STUDENTS-TO-ADD-CODE
date_t date;
int res = sscanf(argv[1]
, "%d-%d-%d"
, &date.year, &date.month, &date.day
);
if (res != 3 || is_valid_date(date) == 0) {
printf("Fehler\n");
return EXIT_FAILURE;
}
// END-STUDENTS-TO-ADD-CODE
// TASK2: calculate the weekday and print it in this format: "%04d-%02d-%02d is a %s\n"
// BEGIN-STUDENTS-TO-ADD-CODE
printf("%04d-%02d-%02d is a ", date.year, date.month, date.day);
print_weekday(calculate_weekday(date));
printf("\n");
// END-STUDENTS-TO-ADD-CODE
return EXIT_SUCCESS;
}