From 309454d34d3cdfc3549213a4469681d259d433ca Mon Sep 17 00:00:00 2001 From: MayorovAY Date: Fri, 12 Dec 2025 18:21:18 +0300 Subject: [PATCH] 2 --- cmake-build-debug/123.txt | 1 + main.cpp | 123 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 cmake-build-debug/123.txt diff --git a/cmake-build-debug/123.txt b/cmake-build-debug/123.txt new file mode 100644 index 0000000..7d030a7 --- /dev/null +++ b/cmake-build-debug/123.txt @@ -0,0 +1 @@ +News,from beyond the Narrow Sea. Haven't you heard? diff --git a/main.cpp b/main.cpp index e1899f0..f1769ac 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,120 @@ -// -// Created by Professional on 12.12.2025. -// +#include +#include +#include +#include -#include "main.h" +int is_valid_filename(char *name) { + // 1) Запрещённые символы + const char *forbidden = "*\"<>?|?"; + for (const char *p = forbidden; *p; ++p) { + if (strchr(name, *p) != NULL) + return 0; + } + + // 2) Двоеточие: только вторым символом, перед ним буква, после "\" + char *colon = strchr(name, ':'); + if (colon) { + if (colon != name + 1) return 0; // не вторым + if (!isalpha((unsigned char)name[0])) return 0; // не буква + if (colon[1] != '\\') return 0; // нет '\' + } + + // 3) Расширение: либо нет, либо .txt (в любом регистре) + char *dot = strrchr(name, '.'); + if (dot) { + char ext[5] = {0}; + strncpy(ext, dot, 4); // ".txt" + '\0' + for (int i = 0; ext[i]; ++i) + ext[i] = (char)tolower((unsigned char)ext[i]); + if (strcmp(ext, ".txt") != 0) + return 0; + } + + return 1; +} + +int main(void) { + char filename[260]; // 4.1: имя файла на стеке + char pattern[256]; // 4.5: строка поиска на стеке + + printf("Enter the file name: "); + if (!fgets(filename, sizeof filename, stdin)) { + printf("Input error\n"); + return 1; + } + // убрать '\n' + filename[strcspn(filename, "\n")] = '\0'; + + // 4.2: проверка имени + if (!is_valid_filename(filename)) { + printf("Incorrect file name\n"); + return 1; + } + + // 4.3: если нет расширения — добавить .txt + if (!strrchr(filename, '.')) { + if (strlen(filename) + 4 >= sizeof filename) { + printf("The file name is too long\n"); + return 1; + } + strcat(filename, ".txt"); + } + + // 4.4: загрузка файла целиком + FILE *f = fopen(filename, "rb"); + if (!f) { + printf("Failed to open file\n"); + return 1; + } + + if (fseek(f, 0, SEEK_END) != 0) { // в конец + printf("Error fseek\n"); + fclose(f); + return 1; + } + long size = ftell(f); // размер файла в байтах + if (size < 0) { + printf("Error ftell\n"); + fclose(f); + return 1; + } + rewind(f); // обратно в начало + + char *text = (char*)malloc((size_t)size + 1); // +1 для '\0' + if (!text) { + printf("Out of memory\n"); + fclose(f); + return 1; + } + + size_t read_bytes = fread(text, 1, (size_t)size, f); + fclose(f); + text[read_bytes] = '\0'; // делаем C‑строку + + // 4.5: строка для поиска + printf("Enter a search string: "); + if (!fgets(pattern, sizeof pattern, stdin)) { + printf("Input error\n"); + free(text); // 4.7 + return 1; + } + pattern[strcspn(pattern, "\n")] = '\0'; + + // 4.6: подсчёт вхождений pattern в text + int count = 0; + size_t pat_len = strlen(pattern); + if (pat_len > 0) { + char *pos = text; + while ((pos = strstr(pos, pattern)) != NULL) { // ищем подстроку + ++count; + pos += pat_len; // идти дальше, можно pos+1, если нужны пересечения + } + } + + printf("Number of occurrences: %d\n", count); + + // 4.7: освобождение + free(text); + + return 0; +} \ No newline at end of file