From ecb28155a6afcbe4c50ebe8e6bc112ff884af48a Mon Sep 17 00:00:00 2001 From: Clay Smith Date: Tue, 1 Aug 2023 01:01:56 -0500 Subject: First commit --- main.c | 317 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 main.c (limited to 'main.c') diff --git a/main.c b/main.c new file mode 100644 index 0000000..89f318f --- /dev/null +++ b/main.c @@ -0,0 +1,317 @@ +#include +#include +#include +#include +#include + + +#define BUFFER_SIZE 1024 +#define NUM_DAYS 7 +#define ASCII_ZERO 48 + + +static char time_string[50]; + + +enum { MONDAY = 0, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }; + + +struct building_info { + char name[100]; + char day_string[NUM_DAYS][50]; //Day of the week letter + 48 '@' or '_' + NULL terminator + struct building_info* next; + int hall_number; //not really sure yet, but I feel like this will be useful later with a more interactive app with a map +}; + + +//negative in start_time means that the building is closed on that day +//in military time xxxx with leading 0s as needed +struct converted_time { + int start_time; + int end_time; +}; + + +void parse_time(char* buf, struct building_info* building_struct); + + +void print_linked_list(struct building_info* first_building); + + +int main(void) +{ + FILE* fptr = fopen("times.txt" , "r"); + if (fptr == NULL) { fprintf(stderr, "Problem reading file times.txt!\n"); exit(-1);} + + char buffer[BUFFER_SIZE]; + struct building_info* current_building = calloc(1, sizeof(struct building_info)); + struct building_info* first_node = current_building; //passed to print_linked_list to print all of them in the end + int num_halls = 0; + + while (fgets(buffer, BUFFER_SIZE, fptr) != NULL) { //while reading the file + if (strstr(buffer, "Monday")) { //parse the times and put them in the struct + parse_time(buffer, current_building); + } else if (buffer[0] >= 'A' && buffer[0] <= 'z') { //new hall, create new node (except for first node) and set name + ++num_halls; + if (current_building->name[0] != 0) { //not first in linked list, have to create a new node + struct building_info* new_building = calloc(1, sizeof(struct building_info)); + current_building->next = new_building; + current_building = new_building; + } + current_building->hall_number = num_halls; + char* name_buffer = (char*) calloc(100, sizeof(char)); + strncpy(name_buffer,buffer, 100); + strncpy(current_building->name, name_buffer, 100); + } + } + print_linked_list(first_node); + return 0; +} + + +//XX:XX [AP]M (can only occur when the [2] index is ':') +//X:XX [AP]M +//XX [AP]M (can only occur when the first X is a 1) (the second X can only be a 0, 1, or 2) +//X [AP]M (X can never be a 0 or a 1) +//need to catch 12 [AP]M - 12:59 [AP]M quirk +int convert_time(char* str, struct converted_time* conv_times) { + int i = 0; + if (str[0] == 'O') { + if (strstr(str, "Open 24 hours") != NULL) { + conv_times->start_time = 0; + conv_times->end_time = 2359; + return 0; + } + } + if (str[0] == 'C') { + conv_times->start_time = -1; + conv_times->end_time = -1; + } else { + for (; i < 2; ++i) { + if (i == 1) { + str = strstr(str, "-"); + str += 2; + if (str == NULL) { + fprintf(stderr, "couldn't find the -\n"); + exit(-1); + } + //handle Noon exception + if ((str[0] == 'N' || str[0] == 'n') && (strstr(str, "Noon") != NULL || strstr(str, "noon") != NULL)) { + conv_times->end_time = 1200; + continue; + } + //Midnight exception + if ((str[0] == 'M' || str[0] == 'm') && (strstr(str, "Midnight") != NULL || strstr(str, "midnight") != NULL)) { + conv_times->end_time = 2359; + continue; + } + } + //handle Noon exception + if ((str[0] == 'N' || str[0] == 'n') && (strstr(str, "Noon") != NULL || strstr(str, "noon") != NULL)) { + conv_times->start_time = 1200; + continue; + } + //Midnight exception + if ((str[0] == 'M' || str[0] == 'm') && (strstr(str, "Midnight") != NULL || strstr(str, "midnight") != NULL)) { + conv_times->end_time = 2359; + continue; + } + if (str[1] == ':') { //has to be X:XX [AP]M format + int hours, minutes; + if (sscanf(str, "%d:%d", &hours, &minutes) != 2) { + fprintf(stderr, "Failed sscanf, which should never occur here\n"); + exit(-1); + } + if (str[5] == 'A') { + if (i == 1) { + conv_times->end_time = hours * 100 + minutes; + } else { + conv_times->start_time = hours * 100 + minutes; + } + } else if (str[5] == 'P') { + if (i == 1) { + conv_times->end_time = (hours + 12) * 100 + minutes; + } else { + conv_times->start_time = (hours + 12) * 100 + minutes; + } + } else { + fprintf(stderr, "In a perfect world, this should never occur\n"); + exit(-1); + } + } else if (str[0] > '1' && str[1] == ' ') { //has to be X [AP]M format + if (str[2] == 'A') { + if (i == 1) { + conv_times->end_time = ((str[0] - ASCII_ZERO) * 100); + } else { + conv_times->start_time = ((str[0] - ASCII_ZERO) * 100); + } + } else if (str[2] == 'P') { + if (i == 1) { + conv_times->end_time = ((str[0] - ASCII_ZERO + 12) * 100); + } else { + conv_times->start_time = ((str[0] - ASCII_ZERO + 12) * 100); + } + } else { + fprintf(stderr, "I do not think this should ever occur when parsing the time and AM/PM\n%s\n", str); + exit(-1); + } + } else { + if (str[2] == ':') { //XX:XX [AP]M format + int hours, minutes; + sscanf(str, "%d:%d", &hours, &minutes); + if (str[6] == 'A') { + if (hours == 12) { + hours = 0; + } else { + hours *= 100; + } + } else if (str[6] == 'P') { + if (hours == 12) { + hours = 1200; + } else { + hours = (hours + 12) * 100; + } + } else { + fprintf(stderr, "Should never occur when parsing the time and AM/PM\n"); + exit(-1); + } + if (i == 1) { + conv_times->end_time = hours + minutes; + } else { + conv_times->start_time = hours + minutes; + } + } else { //XX [AP]M format + int hours; + sscanf(str, "%d", &hours); + if (str[3] == 'A') { + if (hours == 12) { + hours = 0; + } else { + hours *= 100; + } + } else if (str[3] == 'P') { + if (hours == 12) { + hours = 1200; + } else { + hours = (hours + 12) * 100; + } + } else { + fprintf(stderr, "Shouldn't occur when parsing AM/PM\n string was: %s", str); + exit(-1); + } + if (i == 1) { + conv_times->end_time = hours; + } else { + conv_times->start_time = hours; + } + } + } + } + } + + return 0; +} + + +char* string_from_time(struct converted_time* conv_time, int day) { + strncpy(time_string, "-------------------------------------------------", 50); + switch (day) { + case MONDAY: + time_string[0] = 'M'; + break; + case TUESDAY: + time_string[0] = 'T'; + break; + case WEDNESDAY: + time_string[0] = 'W'; + break; + case THURSDAY: + time_string[0] = 'R'; + break; + case FRIDAY: + time_string[0] = 'F'; + break; + case SATURDAY: + time_string[0] = 's'; + break; + case SUNDAY: + time_string[0] = 'S'; + break; + default: + break; + } + + //find starting point + int start_index = (conv_time->start_time / 100) * 2; + int y = (start_index / 2) * 100; + y = conv_time->start_time - y; + if (y > 0) { + start_index++; + if (y > 30) { + start_index++; + } + } + + int end_index = -1; + if (conv_time->start_time > conv_time-> end_time) { + //store end_time in a special variable used to see if another day needs to add time to it + //end of the array is 48 and will be set as our INCLUSIVE end in our for loop + end_index = 48; + } else { + end_index = conv_time->end_time / 100 * 2; + y = (end_index / 2) * 100; + y = conv_time->end_time - y; + if (y > 0) { + end_index++; + if (y > 30) { + end_index++; + } + } + } + + if (start_index == 0) { + start_index = 1; + } + + for (int i = start_index; i <= end_index; ++i) { + time_string[i] = '@'; + } + + return time_string; +} + + +void parse_time(char* buf, struct building_info* building_struct) +{ + //basic setup + enum {MON_OFFSET = 7, TUES_OFFSET = 8, WED_OFFSET = 10, THUR_OFFSET = 9, FRI_OFFSET = 7, SAT_OFFSET = 9, SUN_OFFSET = 7 }; + char* days_of_the_week[] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; + int offset[] = {MON_OFFSET, TUES_OFFSET, WED_OFFSET, THUR_OFFSET, FRI_OFFSET, SAT_OFFSET, SUN_OFFSET}; + struct converted_time conv_times[NUM_DAYS]; + + char* new_buf = strstr(buf, days_of_the_week[0]); + + for (int i = 0; i < NUM_DAYS; ++i) { + new_buf = strstr(new_buf, days_of_the_week[i]); + if (new_buf != NULL) { + new_buf += offset[i]; + convert_time(new_buf, &conv_times[i]); + strncpy(building_struct->day_string[i], string_from_time(&conv_times[i], i), 50); + } else { + fprintf(stderr, "Substring: %s, not found in: %s!\n", days_of_the_week[i], new_buf); + exit(-1); + } + } +} + +void print_linked_list(struct building_info* building) +{ + while (building->next != NULL) { + printf("\n%s", building->name); + for (int i = 0; i < NUM_DAYS; ++i) { + printf("%s\n", building->day_string[i]); + } + printf("0 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 24\n\n"); + building = building->next; + } +} -- cgit v1.2.1