commit 88dd8b8a8a8733e409874c7e8409c13cb7f595ec Author: KochetovaVR Date: Sun Mar 16 20:53:35 2025 +0300 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/task1/CMakeLists.txt b/task1/CMakeLists.txt new file mode 100644 index 0000000..bb00835 --- /dev/null +++ b/task1/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.28) +project(task1) + +set(CMAKE_CXX_STANDARD 17) + +add_executable(task1 main.cpp) diff --git a/task1/main.cpp b/task1/main.cpp new file mode 100644 index 0000000..b31def0 --- /dev/null +++ b/task1/main.cpp @@ -0,0 +1,88 @@ +#include +#include +#include +using namespace std; + +// Вспомогательная функция для преобразования числа от 0 до 15 в шестнадцатеричную цифру +char nibble_to_hex(uint8_t i) { + // Проверка корректности входных данных + assert(0x0 <= i && i <= 0xf); + + // Массив символов для шестнадцатеричных цифр + static const char digits[] = "0123456789abcdef"; + return digits[i]; +} + +// Вспомогательная функция для получения символа бита ('0' или '1') +char bit_digit(uint8_t byte, uint8_t bit) { + return (byte & (0x1 << bit)) ? '1' : '0'; +} + +// Преобразование указателя void* в uint8_t* +const uint8_t* as_bytes(const void* data) { + return reinterpret_cast(data); +} + +// Печать одного байта в шестнадцатеричном виде +void print_in_hex(uint8_t byte) { + // Печать старшего полубайта + cout << nibble_to_hex(byte >> 4); + // Печать младшего полубайта + cout << nibble_to_hex(byte & 0xf); +} + +// Печать блока данных в шестнадцатеричном виде +void print_in_hex(const void* data, size_t size) { + const uint8_t* bytes = as_bytes(data); + for (size_t i = 0; i < size; i++) { + print_in_hex(bytes[i]); + + // Форматирование вывода: пробелы между байтами и перенос строки после 16 байт + if ((i + 1) % 16 == 0) { + cout << '\n'; + } else { + cout << ' '; + } + } +} + +// Печать одного байта в двоичном виде +void print_in_binary(uint8_t byte) { + // Печать всех 8 бит, начиная со старшего + for (int bit = 7; bit >= 0; bit--) { + cout << bit_digit(byte, bit); + } +} + +// Печать блока данных в двоичном виде +void print_in_binary(const void* data, size_t size) { + const uint8_t* bytes = as_bytes(data); + for (size_t i = 0; i < size; i++) { + print_in_binary(bytes[i]); + + // Форматирование вывода: пробелы между байтами и перенос строки после 4 байт + if ((i + 1) % 4 == 0) { + cout << '\n'; + } else { + cout << ' '; + } + } +} + +// Пример использования функций +int main() { + // Тестирование функции nibble_to_hex + assert(nibble_to_hex(0x0) == '0'); + assert(nibble_to_hex(0xa) == 'a'); + assert(nibble_to_hex(0xf) == 'f'); + + // Пример использования функций печати + uint32_t test = 0x42; + cout << "Шестнадцатеричный вывод:\n"; + print_in_hex(&test, sizeof(test)); + cout << "\n\nДвоичный вывод:\n"; + print_in_binary(&test, sizeof(test)); + cout << '\n'; + + return 0; +} \ No newline at end of file diff --git a/task2/CMakeLists.txt b/task2/CMakeLists.txt new file mode 100644 index 0000000..020de24 --- /dev/null +++ b/task2/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.28) +project(task2) + +set(CMAKE_CXX_STANDARD 17) + +add_executable(task2 main.cpp) diff --git a/task2/main.cpp b/task2/main.cpp new file mode 100644 index 0000000..4b2d548 --- /dev/null +++ b/task2/main.cpp @@ -0,0 +1,77 @@ +#include +#include +using namespace std; + +char nibble_to_hex(uint8_t i) { + static const char digits[] = "0123456789ABCDEF"; + return digits[i]; +} + +void print_byte_hex(uint8_t byte) { + cout << nibble_to_hex(byte >> 4) << nibble_to_hex(byte & 0x0F); +} + +void print_hex(uint16_t value) { + uint8_t* bytes = (uint8_t*)&value; + print_byte_hex(bytes[0]); + cout << " "; + print_byte_hex(bytes[1]); +} + +void print_byte_binary(uint8_t byte) { + for (int i = 7; i >= 0; i--) { + cout << ((byte >> i) & 1); + } +} + +void print_binary(uint16_t value) { + uint8_t* bytes = (uint8_t*)&value; + print_byte_binary(bytes[0]); + print_byte_binary(bytes[1]); +} + +int main() { + uint16_t operand1, operand2; + char operation; + + // Ввод данных + cin >> operand1 >> operation >> operand2; + + // Вычисление результата + uint16_t result; + switch (operation) { + case '&': + result = operand1 & operand2; + break; + case '|': + result = operand1 | operand2; + break; + case '^': + result = operand1 ^ operand2; + break; + default: + cout << "Ошибка: поддерживаются только операторы &, | и ^" << endl; + return 1; + } + + // Вывод исходного выражения + cout << operand1 << " " << operation << " " << operand2 << endl; + + // Вывод в шестнадцатеричном виде + print_hex(operand1); + cout << " " << operation << " "; + print_hex(operand2); + cout << " = "; + print_hex(result); + cout << endl; + + // Вывод в двоичном виде + print_binary(operand1); + cout << " " << operation << endl; + print_binary(operand2); + cout << " =" << endl; + print_binary(result); + cout << endl; + + return 0; +} \ No newline at end of file diff --git a/task3/CMakeLists.txt b/task3/CMakeLists.txt new file mode 100644 index 0000000..513def5 --- /dev/null +++ b/task3/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.28) +project(task3) + +set(CMAKE_CXX_STANDARD 17) + +add_executable(task3 main.cpp) diff --git a/task3/main.cpp b/task3/main.cpp new file mode 100644 index 0000000..092c242 --- /dev/null +++ b/task3/main.cpp @@ -0,0 +1,141 @@ +#include +#include +#include +#include +#include +using namespace std; + +struct Student { + char name[17]; + uint16_t year; + float average_score; + uint8_t gender : 1; + uint8_t courses : 7; + Student* head_student; +}; + +void print_hex(const void* data, size_t size) { + const uint8_t* bytes = reinterpret_cast(data); + for (size_t i = 0; i < size; i++) { + cout << hex << uppercase << setw(2) << setfill('0') + << static_cast(bytes[i]) << " "; + } + cout << dec; +} + +void print_binary(const void* data, size_t size) { + const uint8_t* bytes = reinterpret_cast(data); + for (size_t i = 0; i < size; i++) { + for (int j = 7; j >= 0; j--) { + cout << ((bytes[i] >> j) & 1); + } + cout << " "; + } +} + +int main() { + Student students[3]; + + strcpy(students[0].name, "Ivanov Ivan"); + students[0].year = 2023; + students[0].average_score = 4.5f; + students[0].gender = 1; + students[0].courses = 2; + students[0].head_student = nullptr; + + strcpy(students[1].name, "Petrova Anna"); + students[1].year = 2023; + students[1].average_score = 4.8f; + students[1].gender = 0; + students[1].courses = 2; + students[1].head_student = &students[0]; + + strcpy(students[2].name, "Sidorov Petr"); + students[2].year = 2023; + students[2].average_score = 4.2f; + students[2].gender = 1; + students[2].courses = 2; + students[2].head_student = &students[0]; + + cout << "1. Информация о массиве:" << endl; + cout << "Адрес массива: " << &students << endl; + cout << "Размер массива: " << sizeof(students) << " байт" << endl << endl; + + cout << "2. Информация об элементах массива:" << endl; + for (int i = 0; i < 3; i++) { + cout << "Студент " << i << ":" << endl; + cout << "Адрес: " << &students[i] << endl; + cout << "Размер: " << sizeof(Student) << " байт" << endl << endl; + } + + cout << "3. Детальная информация о полях второго студента:" << endl; + + cout << "name:" << endl; + cout << " Адрес: " << static_cast(students[1].name) << endl; + cout << " Смещение: " << offsetof(Student, name) << endl; + cout << " Размер: " << sizeof(students[1].name) << " байт" << endl; + cout << " Hex: "; + print_hex(students[1].name, sizeof(students[1].name)); + cout << endl << " Bin: "; + print_binary(students[1].name, sizeof(students[1].name)); + cout << endl << endl; + + cout << "year:" << endl; + cout << " Адрес: " << &students[1].year << endl; + cout << " Смещение: " << offsetof(Student, year) << endl; + cout << " Размер: " << sizeof(students[1].year) << " байт" << endl; + cout << " Hex: "; + print_hex(&students[1].year, sizeof(students[1].year)); + cout << endl << " Bin: "; + print_binary(&students[1].year, sizeof(students[1].year)); + cout << endl << endl; + + cout << "average_score:" << endl; + cout << " Адрес: " << &students[1].average_score << endl; + cout << " Смещение: " << offsetof(Student, average_score) << endl; + cout << " Размер: " << sizeof(students[1].average_score) << " байт" << endl; + cout << " Hex: "; + print_hex(&students[1].average_score, sizeof(students[1].average_score)); + cout << endl << " Bin: "; + print_binary(&students[1].average_score, sizeof(students[1].average_score)); + cout << endl << endl; + + cout << "head_student:" << endl; + cout << " Адрес: " << &students[1].head_student << endl; + cout << " Смещение: " << offsetof(Student, head_student) << endl; + cout << " Размер: " << sizeof(students[1].head_student) << " байт" << endl; + cout << " Hex: "; + print_hex(&students[1].head_student, sizeof(students[1].head_student)); + cout << endl << " Bin: "; + print_binary(&students[1].head_student, sizeof(students[1].head_student)); + cout << endl << endl; + + cout << "4. Шестнадцатеричное представление структур:" << endl; + for (int i = 0; i < 3; i++) { + cout << "Студент " << i << " (староста: " << (i == 0 ? "да" : "нет") << "):" << endl; + cout << " Все поля: "; + print_hex(&students[i], sizeof(Student)); + cout << endl; + cout << " name: "; + print_hex(&students[i].name, sizeof(students[i].name)); + cout << endl; + cout << " year: "; + print_hex(&students[i].year, sizeof(students[i].year)); + cout << endl; + cout << " average_score: "; + print_hex(&students[i].average_score, sizeof(students[i].average_score)); + cout << endl; + + // Получаем значение байта, содержащего битовые поля + uint8_t bit_fields = (students[i].gender << 7) | students[i].courses; + cout << " gender и courses (как байт): "; + print_hex(&bit_fields, sizeof(bit_fields)); + cout << endl; + + cout << " head_student: "; + print_hex(&students[i].head_student, sizeof(students[i].head_student)); + cout << endl << endl; + } + + return 0; +} \ No newline at end of file diff --git a/task4/CMakeLists.txt b/task4/CMakeLists.txt new file mode 100644 index 0000000..0c344dd --- /dev/null +++ b/task4/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.28) +project(task4) + +set(CMAKE_CXX_STANDARD 17) + +add_executable(task4 main.cpp) diff --git a/task4/main.cpp b/task4/main.cpp new file mode 100644 index 0000000..5ecad7e --- /dev/null +++ b/task4/main.cpp @@ -0,0 +1,173 @@ +#include +#include // Для функций работы с файлами и C-строками +#include // Для функций работы со строками +#include // Для функций проверки символов +#include // Для функций выделения памяти + +using namespace std; + +// Максимальная длина имени файла (предположим 260 символов, типичная максимальная длина пути в Windows) +const size_t MAX_FILENAME_LENGTH = 260; + +// Максимальная длина строки для поиска (предположим 256 символов) +const size_t MAX_SEARCH_STRING_LENGTH = 256; + +// Запрещенные символы в имени файла +const char* forbidden_chars = "*\"<>?|"; + +// Функция для проверки корректности имени файла +bool isValidFilename(const char* filename) { + // Проверка на наличие запрещенных символов + for (size_t i = 0; i < strlen(forbidden_chars); ++i) { + if (strchr(filename, forbidden_chars[i]) != nullptr) { + return false; + } + } + + // Проверка на двоеточие + const char* colon = strchr(filename, ':'); + if (colon != nullptr) { + // Двоеточие должно быть вторым символом + if (colon - filename != 1) { + return false; + } + // Первый символ должен быть буквой + if (!isalpha(filename[0])) { + return false; + } + // После двоеточия должна идти обратная косая черта + if (*(colon + 1) != '\\') { + return false; + } + } + + // Проверка расширения файла + const char* dot = strrchr(filename, '.'); + if (dot != nullptr) { + // Проверяем, что расширение .txt (без учета регистра) + if (strlen(dot) != 4) { // Длина должна быть 4 символа: '.' + 'txt' + return false; + } + // Преобразуем расширение к нижнему регистру для сравнения + char ext[5]; + strncpy(ext, dot, 4); + ext[4] = '\0'; + for (int i = 0; i < 4; ++i) { + ext[i] = tolower(ext[i]); + } + if (strcmp(ext, ".txt") != 0) { + return false; + } + } + + return true; +} + +// Функция для добавления расширения .txt, если его нет +void addTxtExtension(char* filename) { + if (strrchr(filename, '.') == nullptr) { + // Добавляем .txt + strcat(filename, ".txt"); + } +} + +int main() { + // 4.1. Запросить у пользователя имя файла, сохранив его в массиве символов на стеке + char filename[MAX_FILENAME_LENGTH]; + cout << "Введите имя файла: "; + cin.getline(filename, MAX_FILENAME_LENGTH); + + // 4.2. Проверка корректности имени файла + if (!isValidFilename(filename)) { + cout << "Некорректное имя файла." << endl; + return 1; // Завершаем программу с ошибкой + } + + // 4.3. Добавить расширение .txt, если его нет + addTxtExtension(filename); + + // Повторная проверка после добавления расширения + if (!isValidFilename(filename)) { + cout << "Некорректное имя файла после добавления расширения." << endl; + return 1; + } + + // 4.4. Загрузка содержимого файла в память + // Открываем файл в бинарном режиме для точного определения размера + FILE* file = fopen(filename, "rb"); + if (file == nullptr) { + cout << "Не удалось открыть файл: " << filename << endl; + return 1; + } + + // Перемещаемся в конец файла + if (fseek(file, 0, SEEK_END) != 0) { + cout << "Ошибка при перемещении в конец файла." << endl; + fclose(file); + return 1; + } + + // Определяем размер файла + long file_size = ftell(file); + if (file_size == -1L) { + cout << "Не удалось определить размер файла." << endl; + fclose(file); + return 1; + } + + // Возвращаемся в начало файла + rewind(file); + + // Выделяем динамическую память для содержимого файла (+1 для завершающего нуля) + char* file_content = (char*)malloc(file_size + 1); + if (file_content == nullptr) { + cout << "Не удалось выделить память для содержимого файла." << endl; + fclose(file); + return 1; + } + + // Читаем содержимое файла + size_t read_size = fread(file_content, sizeof(char), file_size, file); + if (read_size != (size_t)file_size) { + cout << "Ошибка при чтении файла." << endl; + free(file_content); + fclose(file); + return 1; + } + + // Добавляем завершающий ноль для безопасной работы со строками + file_content[file_size] = '\0'; + + // Закрываем файл + fclose(file); + + // 4.5. Запросить у пользователя строку для поиска, сохранив её в массиве на стеке + char search_string[MAX_SEARCH_STRING_LENGTH]; + cout << "Введите строку для поиска: "; + cin.getline(search_string, MAX_SEARCH_STRING_LENGTH); + + // 4.6. Подсчитать и вывести число вхождений введенной строки в текст файла + int count = 0; + char* pos = file_content; + + // Длина строки для поиска + size_t search_len = strlen(search_string); + if (search_len == 0) { + cout << "Пустая строка для поиска." << endl; + free(file_content); + return 1; + } + + // Поиск всех вхождений + while ((pos = strstr(pos, search_string)) != nullptr) { + count++; + pos += search_len; // Продвигаемся вперед, чтобы избежать бесконечного цикла + } + + cout << "Число вхождений строки \"" << search_string << "\": " << count << endl; + + // 4.7. Освободить выделенную память + free(file_content); + + return 0; +} diff --git a/task4/test.txt b/task4/test.txt new file mode 100644 index 0000000..262d160 --- /dev/null +++ b/task4/test.txt @@ -0,0 +1,2 @@ +Hello world! This is a sample text file. +Hello again. Welcome to the world of C programming. diff --git a/лр4.docx b/лр4.docx new file mode 100644 index 0000000..4f8d4c8 Binary files /dev/null and b/лр4.docx differ