diff --git a/4.cpp b/4.cpp new file mode 100644 index 0000000..fc39933 --- /dev/null +++ b/4.cpp @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include +#include // для setlocale + +const size_t MAX_SIZE = 256; +const char* separators = " \r\n,.!?:;()-"; // Разделители для слов + +// Функция для разделения строки на слова и их вывода +void printWords(const char* text) { + const char* start = text; + + while (true) { + // Пропускаем разделители в начале строки + size_t separator_count = strspn(start, separators); + start += separator_count; + + // Если строка закончилась, выходим + if (start[0] == '\0') { + break; + } + + // Находим длину первого слова + size_t word_length = strcspn(start, separators); + + // Печатаем слово + std::cout.write(start, word_length); + std::cout << std::endl; + + // Сдвигаем указатель на начало следующего слова + start += word_length; + } +} + +// Функция для проверки имени файла на корректность +bool isValidFileName(const char* fileName) { + const char* forbiddenChars = "*\"<>?|"; + if (strpbrk(fileName, forbiddenChars)) { + return false; + } + + const char* colon = strchr(fileName, ':'); + if (colon) { + if (colon != fileName + 1 || !isalpha(fileName[0])) { + return false; + } + if (*(colon + 1) != '\\') { + return false; + } + } + + const char* ext = strrchr(fileName, '.'); + if (ext && _stricmp(ext, ".txt") != 0) { + return false; + } + + return true; +} + +// Функция для подсчета вхождений строки в тексте +int countOccurrences(const char* text, const char* searchStr) { + int count = 0; + const char* p = text; + while ((p = strstr(p, searchStr)) != nullptr) { + count++; + p += strlen(searchStr); // Перемещаем указатель на следующий символ после найденного + } + return count; +} + +int main() { + // Устанавливаем локаль для корректного отображения текста + setlocale(LC_ALL, "Russian"); + + // 4.1 Запрос имени файла + char fileName[MAX_SIZE]; + std::cout << "Введите имя файла: "; + std::cin.getline(fileName, MAX_SIZE); + + // 4.2 Проверка корректности имени файла + while (!isValidFileName(fileName)) { + std::cout << "Некорректное имя файла. Введите заново: "; + std::cin.getline(fileName, MAX_SIZE); + } + + // 4.3 Добавление расширения ".txt", если его нет + if (!strrchr(fileName, '.')) { + strcat_s(fileName, MAX_SIZE, ".txt"); + } + + // 4.4 Открытие файла и загрузка его содержимого + FILE* file = nullptr; + if (fopen_s(&file, fileName, "rb") != 0) { + perror("Ошибка при открытии файла"); + return 1; + } + + fseek(file, 0, SEEK_END); + size_t fileSize = ftell(file); // Изменили на size_t для совместимости с большим размером + fseek(file, 0, SEEK_SET); + + char* content = (char*)malloc(fileSize + 1); + if (content == nullptr) { + perror("Ошибка выделения памяти"); + fclose(file); + return 1; + } + + fread(content, sizeof(char), fileSize, file); + content[fileSize] = '\0'; // Завершающий нуль + fclose(file); + + // 4.5 Запрос строки для поиска + char searchStr[MAX_SIZE]; + std::cout << "Введите строку для поиска: "; + std::cin.getline(searchStr, MAX_SIZE); + + // 4.6 Подсчет вхождений строки в тексте + int occurrences = countOccurrences(content, searchStr); + std::cout << "Строка '" << searchStr << "' встречается " << occurrences << " раз(а) в файле." << std::endl; + + // 4.7 Освобождение памяти + free(content); + + // Дополнительно: Разделение строки на слова + std::cout << "\n--- Разделение строки на слова ---\n"; + char text[MAX_SIZE]; + std::cout << "Введите строку для разделения на слова: "; + std::cin.getline(text, MAX_SIZE); + printWords(text); + + return 0; +}