Вам требуется написать программу на языке 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
.