mirror of
https://github.com/peter-tanner/Systems-programming-labs.git
synced 2024-11-30 10:50:19 +08:00
Workshop solution week 2
This commit is contained in:
parent
b418e749af
commit
b372fafd93
22
Week 2-workshop/README.md
Normal file
22
Week 2-workshop/README.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
## Workshop 1 content
|
||||
Workshop content: https://web.archive.org/web/20210809074913/https://teaching.csse.uwa.edu.au/units/CITS2002/workshops/workshop2.php\
|
||||
`first_day_of_month.c`: https://web.archive.org/web/20210809075040/https://teaching.csse.uwa.edu.au/units/CITS2002/workshops/first_day_of_month.c
|
||||
|
||||
EXTRA WORK
|
||||
* There's some required information that we haven't yet covered in lectures (information we can get from our computer's operating system). Try to identify that extra information.
|
||||
* Consider the file first_day_of_month.c whose function determines the first day (Sun, Mon, ...) of a requested month. Identify the functions that are used to determine this information, and read their documentation for your system.
|
||||
* We know that Linux utility programs can receive optional command-line arguments to specify actions beyond their default actions. In the case of the cal utility, if two (optional) arguments are provided, we are specifying the required month and year to be printed.
|
||||
* Assuming we receive the additional two command-line arguments, which the C program receives as character strings, we can 'convert' their string representations of integers to integer values using the standard atoi() function.
|
||||
* Extend your program to detect optional command-line arguments, and to print the requested calendar.
|
||||
* 🌶 And how could we support left-handers?
|
||||
* 🌶 🌶 Wow! What happened in September 1752? (which you don't have to deal with!) :
|
||||
```
|
||||
prompt> cal 9 1752
|
||||
|
||||
September 1752
|
||||
Su Mo Tu We Th Fr Sa
|
||||
1 2 14 15 16
|
||||
17 18 19 20 21 22 23
|
||||
24 25 26 27 28 29 30
|
||||
```
|
110
Week 2-workshop/cal.c
Normal file
110
Week 2-workshop/cal.c
Normal file
|
@ -0,0 +1,110 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "first_day_of_month.c"
|
||||
#include "year_utils.c"
|
||||
|
||||
#define WEEK_LENGTH 7
|
||||
|
||||
// Adds padding so it's centered.
|
||||
void printHeader(int month, int year) {
|
||||
int len = strlen(MONTH_NAME[month-1]) + 5; // Let's assume the year length is 4.
|
||||
int lPad = (3*WEEK_LENGTH - len)/2;
|
||||
printf("%*s %d\n", 12, MONTH_NAME[month-1], year);
|
||||
}
|
||||
|
||||
static bool LEFT_HAND = false;
|
||||
|
||||
int leftIdx(int i) {
|
||||
switch (LEFT_HAND)
|
||||
{
|
||||
case true:
|
||||
return 6-i;
|
||||
default:
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
void printCal(int month, int year) {
|
||||
printHeader(month, year);
|
||||
for (int i = 0; i < WEEK_LENGTH; i++)
|
||||
{
|
||||
printf("%s ", DAY_NAME[leftIdx(i)]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Original solution just printed but easier to use
|
||||
// 2d array for left hand mode.
|
||||
int limit = monthLimit(month, year);
|
||||
int week[WEEK_LENGTH] = {0};
|
||||
int idx = first_day_of_month(month, year);
|
||||
int day_ = 1;
|
||||
for (int i = 1; i < 6; i++)
|
||||
{
|
||||
while (idx < WEEK_LENGTH)
|
||||
{
|
||||
if (day_ > limit) {
|
||||
break;
|
||||
}
|
||||
week[idx] = day_;
|
||||
day_++;
|
||||
idx++;
|
||||
}
|
||||
|
||||
// print row
|
||||
idx = 0;
|
||||
for (int j = 0; j < WEEK_LENGTH; j++)
|
||||
{
|
||||
int d = week[leftIdx(j)];
|
||||
switch (d)
|
||||
{
|
||||
case 0:
|
||||
printf(" ");
|
||||
break;
|
||||
default:
|
||||
printf("%-3d", d);
|
||||
break;
|
||||
}
|
||||
}
|
||||
memset(week, 0, sizeof week); // clear int array
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
int year = 1;
|
||||
int month = 1;
|
||||
switch (argc)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
{
|
||||
struct tm tm = getCurrentTime();
|
||||
year = tm.tm_year+1900;
|
||||
month = tm.tm_mon+1;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
LEFT_HAND = (strcmp(argv[3], "true") == 0);
|
||||
case 3:
|
||||
year = atoi(argv[1]);
|
||||
month = atoi(argv[2]);
|
||||
if (month >= 1 && month <= 12 && year >= 1) {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printf("Incorrect arguments - expected no arguments or two arguments\ncal year month\ncal year month lefthanded_mode(true|false)\n");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
printCal(month, year);
|
||||
exit(EXIT_SUCCESS);
|
||||
return 0;
|
||||
}
|
28
Week 2-workshop/first_day_of_month.c
Normal file
28
Week 2-workshop/first_day_of_month.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
// written by Chris.McDonald@uwa.edu.au
|
||||
|
||||
// PROVIDED WITHOUT MUCH EXPLANATION YET!
|
||||
|
||||
// RETURNS 0=Sun, 1=Mon, .....
|
||||
//
|
||||
int first_day_of_month(int month, int year)
|
||||
{
|
||||
struct tm tm;
|
||||
|
||||
// SET ALL FIELDS OF tm TO ZERO TO MAKE SOME FIELDS 'UNKNOWN'
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
|
||||
// INITIALIZE THE FILEDS THAT WE ALREADY KNOW
|
||||
tm.tm_mday = 1;
|
||||
tm.tm_mon = month-1; // 0=Jan, 1=Feb, ....
|
||||
tm.tm_year = year-1900;
|
||||
|
||||
// ASK THE POSIX FUNCTION mktime TO DETERMINE THE 'UNKNOWN' FIELDS
|
||||
// See: http://pubs.opengroup.org/onlinepubs/9699919799/
|
||||
mktime(&tm);
|
||||
|
||||
// RETURN THE INTEGER MONTH VALUE
|
||||
return tm.tm_wday; // 0=Sun, 1=Mon, .....
|
||||
}
|
33
Week 2-workshop/year_utils.c
Normal file
33
Week 2-workshop/year_utils.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
|
||||
#include <time.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
static char *DAY_NAME[] = {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"};
|
||||
static char *MONTH_NAME[] = {
|
||||
"January", "February", "March", "April",
|
||||
"May", "June", "July", "August", "September",
|
||||
"October", "November", "December"
|
||||
};
|
||||
|
||||
|
||||
bool isLeapYear(int year) {
|
||||
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
|
||||
}
|
||||
|
||||
int monthLimit(int month, int year)
|
||||
{
|
||||
bool leapYear = isLeapYear(year);
|
||||
switch (month)
|
||||
{
|
||||
case 2:
|
||||
return 28 + leapYear;
|
||||
default:
|
||||
return 31 - (month - 1) % 7 % 2;
|
||||
}
|
||||
}
|
||||
|
||||
struct tm getCurrentTime() {
|
||||
time_t t = time(NULL);
|
||||
struct tm tm = *localtime(&t);
|
||||
return tm;
|
||||
}
|
Loading…
Reference in New Issue
Block a user