Загрузка данных


Да, сейчас напишу все коды для обязательных Quest 1–5 D10T07. Начни с этих файлов в папке src/.

⸻

src/Makefile

.PHONY: all door_struct list_test stack_test print_module documentation_module clean rebuild
CC = gcc
CFLAGS = -Wall -Wextra -Werror
BUILD_DIR = ../build
all: door_struct list_test stack_test print_module documentation_module
door_struct: $(BUILD_DIR)/Quest_1
list_test: $(BUILD_DIR)/Quest_2
stack_test: $(BUILD_DIR)/Quest_3
print_module: $(BUILD_DIR)/Quest_4
documentation_module: $(BUILD_DIR)/Quest_5
$(BUILD_DIR):
	mkdir -p $(BUILD_DIR)
$(BUILD_DIR)/Quest_1: dmanager_module.c door_struct.h | $(BUILD_DIR)
	$(CC) $(CFLAGS) dmanager_module.c -o $(BUILD_DIR)/Quest_1
$(BUILD_DIR)/Quest_2: list.c list_test.c list.h door_struct.h | $(BUILD_DIR)
	$(CC) $(CFLAGS) list.c list_test.c -o $(BUILD_DIR)/Quest_2
$(BUILD_DIR)/Quest_3: stack.c stack_test.c stack.h | $(BUILD_DIR)
	$(CC) $(CFLAGS) stack.c stack_test.c -o $(BUILD_DIR)/Quest_3
$(BUILD_DIR)/Quest_4: main_module_entry_point.c print_module.c print_module.h | $(BUILD_DIR)
	$(CC) $(CFLAGS) main_module_entry_point.c print_module.c -o $(BUILD_DIR)/Quest_4
$(BUILD_DIR)/Quest_5: main_module_entry_point.c documentation_module.c documentation_module.h print_module.c print_module.h | $(BUILD_DIR)
	$(CC) $(CFLAGS) -DDOCUMENTATION_MODE main_module_entry_point.c documentation_module.c print_module.c -o $(BUILD_DIR)/Quest_5
clean:
	rm -rf $(BUILD_DIR)
	rm -f *.o *.a *.so
rebuild: clean all

⸻

Quest 1

src/door_struct.h

#ifndef DOOR_STRUCT_H
#define DOOR_STRUCT_H
struct door {
    int id;
    int status;
};
#endif

src/dmanager_module.c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "door_struct.h"
#define DOORS_COUNT 15
#define MAX_ID_SEED 10000
void initialize_doors(struct door *doors);
void sort_doors(struct door *doors, int count);
void close_doors(struct door *doors, int count);
void output_doors(struct door *doors, int count);
int main(void) {
    struct door doors[DOORS_COUNT];
    initialize_doors(doors);
    sort_doors(doors, DOORS_COUNT);
    close_doors(doors, DOORS_COUNT);
    output_doors(doors, DOORS_COUNT);
    return 0;
}
void sort_doors(struct door *doors, int count) {
    for (int i = 0; i < count - 1; i++) {
        for (int j = 0; j < count - i - 1; j++) {
            if (doors[j].id > doors[j + 1].id) {
                struct door temp = doors[j];
                doors[j] = doors[j + 1];
                doors[j + 1] = temp;
            }
        }
    }
}
void close_doors(struct door *doors, int count) {
    for (int i = 0; i < count; i++) {
        doors[i].status = 0;
    }
}
void output_doors(struct door *doors, int count) {
    for (int i = 0; i < count; i++) {
        printf("%d, %d", doors[i].id, doors[i].status);
        if (i < count - 1) {
            printf("\n");
        }
    }
}
// Doors initialization function
// ATTENTION!!!
// DO NOT CHANGE!
void initialize_doors(struct door *doors) {
    srand(time(0));
    int seed = rand() % MAX_ID_SEED;
    for (int i = 0; i < DOORS_COUNT; i++) {
        doors[i].id = (i + seed) % DOORS_COUNT;
        doors[i].status = rand() % 2;
    }
}

⸻

Quest 2

src/list.h

#ifndef LIST_H
#define LIST_H
#include "door_struct.h"
struct node {
    struct door data;
    struct node *next;
};
struct node *init(struct door door);
struct node *add_door(struct node *elem, struct door door);
struct node *find_door(int door_id, struct node *root);
struct node *remove_door(struct node *elem, struct node *root);
void destroy(struct node *root);
#endif

src/list.c

#include "list.h"
#include <stdlib.h>
struct node *init(struct door door) {
    struct node *root = malloc(sizeof(struct node));
    if (root != NULL) {
        root->data = door;
        root->next = NULL;
    }
    return root;
}
struct node *add_door(struct node *elem, struct door door) {
    struct node *new_node = NULL;
    if (elem != NULL) {
        new_node = malloc(sizeof(struct node));
        if (new_node != NULL) {
            new_node->data = door;
            new_node->next = elem->next;
            elem->next = new_node;
        }
    }
    return new_node;
}
struct node *find_door(int door_id, struct node *root) {
    struct node *result = NULL;
    struct node *current = root;
    while (current != NULL && result == NULL) {
        if (current->data.id == door_id) {
            result = current;
        }
        current = current->next;
    }
    return result;
}
struct node *remove_door(struct node *elem, struct node *root) {
    struct node *result = root;
    if (elem != NULL && root != NULL) {
        if (elem == root) {
            result = root->next;
            free(root);
        } else {
            struct node *current = root;
            while (current->next != NULL && current->next != elem) {
                current = current->next;
            }
            if (current->next == elem) {
                current->next = elem->next;
                free(elem);
            }
        }
    }
    return result;
}
void destroy(struct node *root) {
    while (root != NULL) {
        struct node *next = root->next;
        free(root);
        root = next;
    }
}

src/list_test.c

#include <stdio.h>
#include "list.h"
#define SUCCESS 1
#define FAIL 0
int add_door_test(void);
int remove_door_test(void);
void print_result(const char *test_name, int result);
int main(void) {
    print_result("add_door", add_door_test());
    print_result("remove_door", remove_door_test());
    return 0;
}
int add_door_test(void) {
    int result = FAIL;
    struct door first = {1, 0};
    struct door second = {2, 1};
    struct node *root = init(first);
    if (root != NULL) {
        struct node *added = add_door(root, second);
        if (added != NULL && root->next == added && added->data.id == 2 && added->data.status == 1 &&
            added->next == NULL) {
            result = SUCCESS;
        }
    }
    destroy(root);
    return result;
}
int remove_door_test(void) {
    int result = FAIL;
    struct door first = {1, 0};
    struct door second = {2, 0};
    struct door third = {3, 1};
    struct node *root = init(first);
    if (root != NULL) {
        struct node *second_node = add_door(root, second);
        struct node *third_node = add_door(second_node, third);
        if (second_node != NULL && third_node != NULL) {
            root = remove_door(second_node, root);
            if (root != NULL && root->next == third_node && find_door(2, root) == NULL) {
                root = remove_door(root, root);
                if (root == third_node && find_door(1, root) == NULL) {
                    root = remove_door(third_node, root);
                    if (root == NULL) {
                        result = SUCCESS;
                    }
                }
            }
        }
    }
    destroy(root);
    return result;
}
void print_result(const char *test_name, int result) {
    printf("%s: ", test_name);
    if (result == SUCCESS) {
        printf("SUCCESS");
    } else {
        printf("FAIL");
    }
    printf("\n");
}

⸻

Quest 3

src/stack.h

#ifndef STACK_H
#define STACK_H
struct stack_node {
    int data;
    struct stack_node *next;
};
struct stack {
    struct stack_node *top;
};
struct stack *init(void);
int push(struct stack *stack, int value);
int pop(struct stack *stack, int *value);
void destroy(struct stack *stack);
#endif

src/stack.c

#include "stack.h"
#include <stdlib.h>
struct stack *init(void) {
    struct stack *stack = malloc(sizeof(struct stack));
    if (stack != NULL) {
        stack->top = NULL;
    }
    return stack;
}
int push(struct stack *stack, int value) {
    int result = 0;
    if (stack != NULL) {
        struct stack_node *new_node = malloc(sizeof(struct stack_node));
        if (new_node != NULL) {
            new_node->data = value;
            new_node->next = stack->top;
            stack->top = new_node;
            result = 1;
        }
    }
    return result;
}
int pop(struct stack *stack, int *value) {
    int result = 0;
    if (stack != NULL && stack->top != NULL && value != NULL) {
        struct stack_node *old_top = stack->top;
        *value = old_top->data;
        stack->top = old_top->next;
        free(old_top);
        result = 1;
    }
    return result;
}
void destroy(struct stack *stack) {
    if (stack != NULL) {
        while (stack->top != NULL) {
            struct stack_node *old_top = stack->top;
            stack->top = old_top->next;
            free(old_top);
        }
        free(stack);
    }
}

src/stack_test.c

#include <stdio.h>
#include "stack.h"
#define SUCCESS 1
#define FAIL 0
int push_test(void);
int pop_test(void);
void print_result(const char *test_name, int result);
int main(void) {
    print_result("push", push_test());
    print_result("pop", pop_test());
    return 0;
}
int push_test(void) {
    int result = FAIL;
    struct stack *stack = init();
    if (stack != NULL && push(stack, 10) && stack->top != NULL && stack->top->data == 10) {
        result = SUCCESS;
    }
    destroy(stack);
    return result;
}
int pop_test(void) {
    int result = FAIL;
    int value = 0;
    struct stack *stack = init();
    if (stack != NULL && push(stack, 1) && push(stack, 2) && push(stack, 3)) {
        if (pop(stack, &value) && value == 3 && pop(stack, &value) && value == 2 && pop(stack, &value) &&
            value == 1 && !pop(stack, &value)) {
            result = SUCCESS;
        }
    }
    destroy(stack);
    return result;
}
void print_result(const char *test_name, int result) {
    printf("%s: ", test_name);
    if (result == SUCCESS) {
        printf("SUCCESS");
    } else {
        printf("FAIL");
    }
    printf("\n");
}

⸻

Quest 4

src/print_module.h

#ifndef PRINT_MODULE_H
#define PRINT_MODULE_H
#define MODULE_LOAD_SUCCESS_MESSAGE "Output stream module load: success"
#define LOG_PREFIX "[LOG]"
void print_log(char (*print)(char), char *message);
char print_char(char ch);
#endif

src/print_module.c

#include "print_module.h"
#include <stdio.h>
#include <time.h>
char print_char(char ch) {
    putchar(ch);
    return ch;
}
void print_log(char (*print)(char), char *message) {
    time_t current_time = time(NULL);
    struct tm *time_info = localtime(&current_time);
    char buffer[9];
    if (print != NULL && message != NULL && time_info != NULL) {
        strftime(buffer, sizeof(buffer), "%H:%M:%S", time_info);
        for (int i = 0; LOG_PREFIX[i] != '\0'; i++) {
            print(LOG_PREFIX[i]);
        }
        print(' ');
        for (int i = 0; buffer[i] != '\0'; i++) {
            print(buffer[i]);
        }
        print(' ');
        for (int i = 0; message[i] != '\0'; i++) {
            print(message[i]);
        }
        print('\n');
    }
}

⸻

Quest 5

src/documentation_module.h

#ifndef DOCUMENTATION_MODULE_H
#define DOCUMENTATION_MODULE_H
#define DOCUMENTS_COUNT 4
#define DOCUMENTS "Linked lists", "Queues", "Maps", "Binary Trees"
#define AVAILABLE_DOCUMENT "Binary Trees"
int *check_available_documentation_module(int (*validate)(char *), int document_count, ...);
int validate(char *data);
#endif

src/documentation_module.c

#include "documentation_module.h"
#include <stdarg.h>
#include <stdlib.h>
int validate(char *data) {
    int result = 1;
    char available[] = AVAILABLE_DOCUMENT;
    if (data == NULL) {
        result = 0;
    } else {
        int i = 0;
        while (data[i] != '\0' && available[i] != '\0' && result) {
            if (data[i] != available[i]) {
                result = 0;
            }
            i++;
        }
        if (data[i] != available[i]) {
            result = 0;
        }
    }
    return result;
}
int *check_available_documentation_module(int (*validate)(char *), int document_count, ...) {
    int *result = NULL;
    if (validate != NULL && document_count > 0) {
        result = malloc(document_count * sizeof(int));
        if (result != NULL) {
            va_list documents;
            va_start(documents, document_count);
            for (int i = 0; i < document_count; i++) {
                char *document = va_arg(documents, char *);
                result[i] = validate(document);
            }
            va_end(documents);
        }
    }
    return result;
}

src/main_module_entry_point.c

#include <stdio.h>
#include <stdlib.h>
#include "documentation_module.h"
#include "print_module.h"
#ifdef DOCUMENTATION_MODE
int main(void) {
    char *documents[DOCUMENTS_COUNT] = {DOCUMENTS};
    int *availability = check_available_documentation_module(validate, DOCUMENTS_COUNT, DOCUMENTS);
    if (availability == NULL) {
        printf("n/a");
    } else {
        for (int i = 0; i < DOCUMENTS_COUNT; i++) {
            printf("[%15s : %s]", documents[i], availability[i] ? "available" : "unavailable");
            if (i < DOCUMENTS_COUNT - 1) {
                printf("\n");
            }
        }
    }
    free(availability);
    return 0;
}
#else
int main(void) {
    print_log(print_char, MODULE_LOAD_SUCCESS_MESSAGE);
    return 0;
}
#endif

⸻

Как проверить после вставки файлов

Из папки src:

cp ../materials/linters/.clang-format .
find . \( -name "*.c" -o -name "*.h" \) -exec clang-format -i {} \;
find . \( -name "*.c" -o -name "*.h" \) -exec clang-format -n {} \;

Сборка:

make clean
make all

Запуск:

../build/Quest_1
../build/Quest_2
../build/Quest_3
../build/Quest_4
../build/Quest_5

Память:

valgrind --tool=memcheck --leak-check=yes ../build/Quest_1
valgrind --tool=memcheck --leak-check=yes ../build/Quest_2
valgrind --tool=memcheck --leak-check=yes ../build/Quest_3
valgrind --tool=memcheck --leak-check=yes ../build/Quest_4
valgrind --tool=memcheck --leak-check=yes ../build/Quest_5

Перед коммитом:

make clean
rm -rf ../build
git status