#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; } }