I have an assignment from college, in which I have to use C to pack three unsigned integers representing a date (the year must be between 1970 and 2097) and compress it into an unsigned short, then unpack it again and show it in command line.
Can someone help me please?
Below I leave the code I have so far (declared variables outside functions and function signatures cannot be changed)
Edit: I have a second problem, which is the getchar function not return anything, setting the three date fields to 0...
#include <stdio.h>
typedef unsigned short pkdate_t;
typedef struct date3 {
unsigned year;
unsigned month;
unsigned day;
} date3_t;
int ror (int val, unsigned n) {
return (val >> n)|(n << (32 - n));
}
int pack_date (pkdate_t * dst, date3_t * src) {
if ((*src).year < 1097 || (*src).year > 2097 || (*src).month < 1 || (*src).month > 12 || (*src).day < 1 ||
((*src).month == 2 && (((*src).year / 4 == 0 && (*src).day > 29) || ((*src).year / 4 != 0 && (*src).day > 28))) ||
(((*src).month == 2 || (*src).month == 4 || (*src).month == 6 || (*src).month == 9 || (*src).month == 11) && (*src).day == 31)) return -1;
//(*dst) = (*src).year * 10 + (*src).month + (*src).day; "wrong code"
return 0;
}
int unpack_date (date3_t * dst, pkdate_t date) {
(*dst).year = date % 10000;
date = date / 10000;
(*dst).month = date % 100;
date = date / 100;
(*dst).day = date % 100;
if ((*dst).year < 1097 || (*dst).year > 2097 || (*dst).month < 1 || (*dst).month > 12 || (*dst).day < 1 ||
((*dst).month == 2 && (((*dst).year / 4 == 0 && (*dst).day > 29) || ((*dst).year / 4 != 0 && (*dst).day > 28))) ||
(((*dst).month == 2 || (*dst).month == 4 || (*dst).month == 6 || (*dst).month == 9 || (*dst).month == 11) && (*dst).day == 31)) return -1;
else return 0;
}
int main () {
int k = ror(30, 2);
printf("%s\n", "exercicio 1:");
printf("%d turned into %d\n", 30, k);
pkdate_t date = 0;
date3_t newDate;
newDate.year = 2000;
newDate.month = 04;
newDate.day = 02;
printf("%s\n", "exercicio 2:");
//printf("%s\n", "insira uma data (yyyymmdd) e de seguida pressione enter:");
//int i = 1000;
//while (i > 0) {
//newDate.year += getchar() * i;
//i = i / 10;
//}
//i = 10;
//while (i > 0) {
//newDate.month += getchar() * i;
//i = i / 10;
//}
//i = 10;
//while (i > 0) {
//newDate.day += getchar() * i;
//i = i / 10;
//}
//"the commented part above does not get any values from command line, still figuring that part out :)"
pack_date(&date, &newDate);
printf("packed date: %hu\n", date);
unpack_date(&newDate, date);
printf("unpacked date: %u/%u/%u\n", newDate.year, newDate.month, newDate.day);
//newDate.year = 2000;
//newDate.month = 12;
//newDate.day = 14;
//pack_date(&date, &newDate);
//printf("%s\n", "exercicio 3:");
//printf("date is %hu\n", date);
// "ignore"
return 0;
}
In C, there aren't so much use cases that qualify for bitfields, but this one is a perfect fit IMHO since it saves you a lot of headaches from bit shifting:
struct date_struct
{
unsigned short year:7;
unsigned short month:4;
unsigned short day:5;
};
union date
{
struct date_struct bits;
short date;
}