Task 3 – Алексей Щербаков Описание
Проект реализует консольную утилиту на C, которая:
читает вход построчно (до EOF) блоками фиксированной длины,
разбивает каждую строку на слова с «жадным» выделением специальных токенов,
печатает список слов в исходном порядке,
печатает те же слова в лексикографическом порядке (пузырьковая сортировка).
Типы слов
Простые: буквы/цифры и символы _ / . $
Специальные (жадно): |, , &, &&, ;, >, >>, <, (, )
Пример: cat|sort&&ls>>file → cat, |, sort, &&, ls, >>, file
→ >>, >
Структура проекта Task_3/ main.c // Чтение блоками (fscanf + getsym), конечный автомат, разбор слов, вывод list.c // Структура «список строк» и функции работы с ней (динамический массив) Makefile // Сборка из модулей .gitignore // Игнор бинарников/временных файлов (по желанию)
Компиляция
Требуется gcc и make.
make # соберёт исполняемый файл 'prog' make clean # очистит объектные и бинарные файлы
Замечание: Makefile настроен на C99:
CFLAGS = -g -Wall -std=c99 -pedantic
Запуск
Ввод можно давать из клавиатуры или перенаправить из файла.
Ручной ввод ./prog cat|sort&&ls>>file <Ctrl+D> # завершить ввод (Linux/macOS; в Windows Git Bash/WSL тоже)
Из файла echo "cat|sort&&ls>>file" > test.txt ./prog < test.txt
Формат вывода
Для каждой входной строки печатаются два списка:
исходный порядок,
лексикографический порядок.
Оба списка печатаются в формате:
первая строка — длина списка,
далее — по одному слову на строку.
Пример вывода для cat|sort&&ls>>file:
7 cat | sort && ls
file 7 && |
cat file ls sort
Реализация
- Ввод блоками (без посимвольного getchar)
Фиксированный размер блока BLK (по умолчанию 64).
Чтение через fscanf со строкой формата "%BLK[^\n]" (до перевода строки).
Функция getsym() выдаёт символы по одному, автоматически рефиллит блоки и возвращает '\n' как разделитель строк, EOF при конце ввода.
- Лексер (конечный автомат)
Состояния: Start, Word, Pipe, Pipe2, Amp, Amp2, Greater, Greater2, SingleSpec, Newline, Stop. Логика:
В Start пропускаем пробелы/табы, обрабатываем EOF/'\n', иначе стартуем токен:
если первый символ |, &, > — проверяем второй для , &&, >>;
одиночные спецсимволы <, ;, (, ) — отдельные токены;
иначе собираем простое слово (буквы/цифры/_/. $).
«Жадность» специальных токенов соблюдается (например, >>> → >>, >).
- Структура данных «список строк»
Представлена динамическим массивом char **lst.
Рост массивов/буферов пакетами по SIZE (по умолчанию 16).
Функции:
null_list, clearlist, termlist, printlist,
list_append (добавить готовую строку),
sortlist (пузырьковая сортировка).
Вся динамическая память корректно освобождается (free) в clearlist.
- Сортировка
Пузырьковая (на месте), сравнение strcmp.
- Обработка ошибок
Нехватка памяти (OOM) при realloc/malloc → информативные сообщения в stderr. В критических местах — завершение программы, в некритических — попытка продолжить.
Примеры тестов
echo "cat|sort&&ls>>file" | ./prog
printf "a||b&&c>d<e\n" | ./prog
cat << 'EOF' | ./prog ls -l|grep txt >out.txt echo&&cat<file.txt;ls
(a)&& b || c EOF
Ожидается корректное разбиение на слова и печать двух списков для каждой строки.