Вам требуется написать программу на языке C++ в файле src/main.cpp, которая:
- Принимает два аргумента командной строки: имя входного файла и некоторую непустую строку.
- Выводит
Yes, если удалось найти заданную строку как подстроку в заданном файле. - Выводит
Noв случае, если не удалось найти строку и ошибки не произошло. - В случае, если количество входных параметров не равно двум (
argc != 3), необходимо вернуть ненулевой код ошибки и вывести некоторое информативное сообщение вstderr. - Аналогично нужно поступать в случае любых других ошибок, в том числе ошибок I/O.
- Решение должно использовать функции из <cstdio>, а не stream I/O из C++.
- Для выделения памяти используйте
std::malloc. - Нельзя использовать исключения и части стандартной библиотеки, оперирующие ими (для этого будут другие практики, здесь одна из целей — прочувствовать, как живут на Си).
- Программа должна работать за
O(n + m), гдеn— размер файла, аm— длина строки из аргумента. Для эффективного поиска подстроки можно использовать, например, алгоритм Кнута-Морриса-Пратта.
Допустим, в файле foo.txt лежит строка ababar, а файла bar.txt не существует вовсе.
$ ./substr foo.txt 'abar'должен вывести Yes и вернуть код ошибки 0.
$ ./substr foo.txt 'abaz'должен вывести No и вернуть код ошибки 0.
$ ./substr bar.txt 'abaz'должен вернуть ненулевой код ошибки и вывести в stderr сообщение об ошибке, информирующее о том, что файла не существует.
Вам предлагается начать использовать систему автоматизации сборки CMake. Она широко распространена, а также будет использована во всех последующих заданиях. Конфигурации CMake-проектов определяются файлом CMakeLists.txt.
CMake — это не система сборки, а способ её автоматизации. CMake генерирует конфигурацию для существующих систем сборки, например для Make или Ninja, и затем использует их. Список поддерживаемых генераторов можно увидеть в выводе cmake --help.
Все сниппеты приведённые ниже, начинающиеся со знака $, должны рассматриваться как команды bash.
- Запустим процесс конфигурации для отладочного билда с санитайзерами (санитайзеры инструментируют код, чтобы в рантайме вылавливать ошибки обращения к памяти и пр.):
где
$ cmake -S . -B build-debug \ -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZERS=ON-S— корневая директория CMake-проекта;-B— директория, куда CMake положит все генерируемые конфигурации и артифакты;-DCMAKE_BUILD_TYPE— режим сборки, может влиять на различные флаги компилятора и линковщика (например,-gдля дебага);-DUSE_SANITIZERS— включить санитайзеры (см., как используется этот параметр вCMakeLists.txt).
- Типичные конфигурации компиляции вынесены в
CMakePresets.json, поэтому команду можно упростить с использованием--preset:$ cmake -S . -B build-debug --preset SanitizedDebug - Теперь, используя сгенерированные конфигурации для билд-системы, можно запустить процесс сборки:
$ cmake --build build-debug
- После успешной сборки проекта в директории
build-debugдолжен появиться исполняемый файлsubstr(по имени таргета вCMakeLists.txt), можем запустить его:$ build/substr
Для удобства описанные команды вынесены в скрипт build.sh — можете использовать его для компиляции с использованием различных пресетов.
Весь описанный процесс сборки может быть автоматизирован при помощи IDE.
Например, в последней версии CLion достаточно просто открыть проект, чтобы он сам подтянул все доступные пресеты и сгенерировал профили запуска. Активировать эти профили можно в File->Settings->Build,Execution...->CMake.