From e959051d3fc2950bbcff9a4fb0b41060748b8143 Mon Sep 17 00:00:00 2001 From: IvanchenkoIS Date: Mon, 23 Dec 2024 18:48:30 +0000 Subject: [PATCH] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B8=D0=BB(?= =?UTF-8?q?=D0=B0)=20=D0=BD=D0=B0=20'4.cpp'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 4.cpp | 130 +++++++++++++++++++--------------------------------------- 1 file changed, 42 insertions(+), 88 deletions(-) diff --git a/4.cpp b/4.cpp index 5ecad7e..6740be2 100644 --- a/4.cpp +++ b/4.cpp @@ -1,173 +1,127 @@ #include -#include // Для функций работы с файлами и C-строками -#include // Для функций работы со строками -#include // Для функций проверки символов -#include // Для функций выделения памяти +#include // Для работы с файлами и C-строками +#include // Для обработки строк +#include // Для проверки символов +#include // Для управления памятью using namespace std; -// Максимальная длина имени файла (предположим 260 символов, типичная максимальная длина пути в Windows) -const size_t MAX_FILENAME_LENGTH = 260; +const size_t MAX_FILENAME_LENGTH = 260; // Максимальная длина имени файла +const size_t MAX_SEARCH_STRING_LENGTH = 256; // Максимальная длина строки поиска -// Максимальная длина строки для поиска (предположим 256 символов) -const size_t MAX_SEARCH_STRING_LENGTH = 256; +const char* invalid_chars = "*\"<>?|"; -// Запрещенные символы в имени файла -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) { + for (size_t i = 0; i < strlen(invalid_chars); ++i) { + if (strchr(filename, invalid_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) != '\\') { + if (colon - filename != 1 || !isalpha(filename[0]) || *(colon + 1) != '\\') { return false; } } - // Проверка расширения файла - const char* dot = strrchr(filename, '.'); - if (dot != nullptr) { - // Проверяем, что расширение .txt (без учета регистра) - if (strlen(dot) != 4) { // Длина должна быть 4 символа: '.' + 'txt' - return false; - } - // Преобразуем расширение к нижнему регистру для сравнения + const char* extension = strrchr(filename, '.'); + if (extension != nullptr) { + if (strlen(extension) != 4) return false; + char ext[5]; - strncpy(ext, dot, 4); + strncpy(ext, extension, 4); ext[4] = '\0'; - for (int i = 0; i < 4; ++i) { - ext[i] = tolower(ext[i]); - } - if (strcmp(ext, ".txt") != 0) { - return false; - } + for (int i = 0; i < 4; ++i) ext[i] = tolower(ext[i]); + return strcmp(ext, ".txt") == 0; } return true; } -// Функция для добавления расширения .txt, если его нет -void addTxtExtension(char* filename) { +void ensureTxtExtension(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; // Завершаем программу с ошибкой + cout << "Неверное имя файла." << endl; + return 1; } - // 4.3. Добавить расширение .txt, если его нет - addTxtExtension(filename); + ensureTxtExtension(filename); - // Повторная проверка после добавления расширения if (!isValidFilename(filename)) { - cout << "Некорректное имя файла после добавления расширения." << endl; + cout << "Ошибка в имени после добавления расширения." << endl; return 1; } - // 4.4. Загрузка содержимого файла в память - // Открываем файл в бинарном режиме для точного определения размера FILE* file = fopen(filename, "rb"); if (file == nullptr) { - cout << "Не удалось открыть файл: " << filename << endl; + cout << "Ошибка открытия файла: " << filename << endl; return 1; } - // Перемещаемся в конец файла if (fseek(file, 0, SEEK_END) != 0) { - cout << "Ошибка при перемещении в конец файла." << endl; + cout << "Ошибка перехода в конец файла." << endl; fclose(file); return 1; } - // Определяем размер файла long file_size = ftell(file); if (file_size == -1L) { - cout << "Не удалось определить размер файла." << endl; + cout << "Не удалось узнать размер файла." << endl; fclose(file); return 1; } - // Возвращаемся в начало файла rewind(file); - // Выделяем динамическую память для содержимого файла (+1 для завершающего нуля) - char* file_content = (char*)malloc(file_size + 1); - if (file_content == nullptr) { - cout << "Не удалось выделить память для содержимого файла." << endl; + char* content = (char*)malloc(file_size + 1); + if (content == nullptr) { + cout << "Ошибка выделения памяти." << endl; fclose(file); return 1; } - // Читаем содержимое файла - size_t read_size = fread(file_content, sizeof(char), file_size, file); + size_t read_size = fread(content, sizeof(char), file_size, file); if (read_size != (size_t)file_size) { - cout << "Ошибка при чтении файла." << endl; - free(file_content); + cout << "Ошибка чтения файла." << endl; + free(content); fclose(file); return 1; } - // Добавляем завершающий ноль для безопасной работы со строками - file_content[file_size] = '\0'; - - // Закрываем файл + content[file_size] = '\0'; fclose(file); - // 4.5. Запросить у пользователя строку для поиска, сохранив её в массиве на стеке - char search_string[MAX_SEARCH_STRING_LENGTH]; + char search_str[MAX_SEARCH_STRING_LENGTH]; cout << "Введите строку для поиска: "; - cin.getline(search_string, MAX_SEARCH_STRING_LENGTH); + cin.getline(search_str, MAX_SEARCH_STRING_LENGTH); - // 4.6. Подсчитать и вывести число вхождений введенной строки в текст файла int count = 0; - char* pos = file_content; + char* pos = content; - // Длина строки для поиска - size_t search_len = strlen(search_string); + size_t search_len = strlen(search_str); if (search_len == 0) { cout << "Пустая строка для поиска." << endl; - free(file_content); + free(content); return 1; } - // Поиск всех вхождений - while ((pos = strstr(pos, search_string)) != nullptr) { + while ((pos = strstr(pos, search_str)) != nullptr) { count++; - pos += search_len; // Продвигаемся вперед, чтобы избежать бесконечного цикла + pos += search_len; } - cout << "Число вхождений строки \"" << search_string << "\": " << count << endl; - - // 4.7. Освободить выделенную память - free(file_content); + cout << "Частота появления строки \"" << search_str << "\": " << count << endl; + free(content); return 0; -} +} \ No newline at end of file