Загрузка данных
Да, сейчас напишу все коды для обязательных 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(¤t_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