# С: Отчёт по четвертой лабораторной работе ## Оглавление. [[_TOC_]] ## Задача 1. ### Условие. Самостоятельно реализовать указанные строковые функции: * strspn ### Решение. `size_t my_strspn(const char *s, const char *accept)` возращает длину максимальной начальной подстроки строки `s`, содержащей только символы из набора `accept` ## Задача 2. ### Условие. Написать программу, которая запрашивает у пользователя одну или две строки, разбивает строку (или строки) на слова и выполняет обработку этих слов. Разбиение строки на слова реализуется самостоятельно (использовать для выделения слов функции scanf, sscanf или strtok нельзя). В результате разбора строки должен быть сформирован массив слов (один или несколько). После чего выполняется обработка одного или нескольких массивов слов. Длина строки не превышает 256 символов, длина слова - 16-ти символов. Слова разделяются одним или несколькими пробелами и знаками пунктуации (“,”, “;”, “:”, “-”, “.”, “!”, “?”). Результаты выводятся обязательно после фразы "Result:" (кавычки не нужны). Слова (или слова и числа) разделяются одним пробелом. В случае если задача решение не может быть получено, на экран ничего не выводится, возвращается код ошибки. Обратите внимание на ограничения по длине строке и по длине слова. Ввести две строки. Напечатать слова, которые встречаются в двух строках только один раз (т.е. один раз либо в первой, либо во второй). Сначала выводятся слова из первой строки (в том порядке, в котором они встретились в этой строке), затем слова из второй строки. ### Решение. Разбил задачу на следующие функции: - `transform` - преобразование матрицы типа `a[N][M]` к типу `**a` - `input_string` - ввод строки - `split_words` - разбитие строки на слова - `is_determintator` - проверка символа на пренадлежность к разделителям - `unique_words` - удаление из массива слов, всех повторяющихся слов - `print_words` - вывод слов - `remove_word` - удаление определенного слова по его значению из массива - `remove_element` - удаление элемента из массива по индексу ### Тестирование. Написал тесты и произвёл тестирование программы. Проверяю покрытие тестами. ``` $ make test gcc -Wall -Wextra -Werror -O0 -Wvla -std=c99 -pedantic -fprofile-arcs -ftest-coverage -o test.out ./main.c ./utils.c ./test.out < ./tests/in_1.txt > temp.out; ./test.out < ./tests/in_2.txt > temp.out; ./test.out < ./tests/in_3.txt > temp.out; ./test.out < ./tests/in_4.txt > temp.out; ./test.out < ./tests/in_5.txt > temp.out; ./test.out < ./tests/in_6.txt > temp.out; ./test.out < ./tests/in_7.txt > temp.out; ./test.out < ./tests/in_8.txt > temp.out; gcov ./main.c; gcov ./utils.c; File 'main.c' Lines executed:100.00% of 25 Creating 'main.c.gcov' File 'utils.c' Lines executed:91.67% of 84 Creating 'utils.c.gcov' rm -rf temp.out ``` Не удалось достичь 100% покрытия кода. Рассмотрим вывод утилиты `gcov`. Не покрыты тестами только участки кода, отвечающие за проверку нулевых указателей и проверку на корректность передаваемых аргументов. ## Задача 3. ### Условие. Для решения этой задачи нужно использовать функции стандартной библиотеки для обработки строк. Написать программу, которая запрашивает у пользователя строку, разбивает строку на слова. В результате разбора строки формируется массив слов. Максимальные длины строки и слова, разделители слов такие же как в задаче 2. Из слов, отличных от последнего, составляется новая строка, в которой слова разделяются одним пробелом. Слова в результирующую строку помещаются в обратном порядке. После последнего слова в результирующей строке пробел не добавляется. Прежде, чем очередное слово помещается в результирующую строку, оно подвергается указанному преобразованию. Если результирующая строка не пустая, она выводится на экран с помощью вызова функции printf следующим образом `printf("Result: %s\n", new_str);` Преобразование слова: Оставить в слове только первые вхождения каждой буквы. ### Решение. Разбил задачу на следующие функции: - `transform` - преобразование матрицы типа `a[N][M]` к типу `**a` - `input_string` - ввод строки - `split_words` - разбитие строки на слова - `is_determintator` - проверка символа на пренадлежность к разделителям - `remove_word` - удаление определенного слова по его значению из массива - `remove_element` - удаление элемента из массива по индексу - `unique_letters` - удаление всех повторов букв из строки - `remove_char` - удаление символа из строки по индексу - `store_words` - сохранение слов в строку по условию задачи ### Тестирование. Написал тесты и произвёл тестирование программы. Проверяю покрытие тестами. ``` $ make test gcc -Wall -Wextra -Werror -O0 -Wvla -std=c99 -pedantic -fprofile-arcs -ftest-coverage -o test.out ./main.c ./utils.c ./test.out < ./tests/in_1.txt > temp.out; ./test.out < ./tests/in_2.txt > temp.out; ./test.out < ./tests/in_3.txt > temp.out; ./test.out < ./tests/in_4.txt > temp.out; ./test.out < ./tests/in_5.txt > temp.out; ./test.out < ./tests/in_6.txt > temp.out; ./test.out < ./tests/in_7.txt > temp.out; gcov ./main.c; gcov ./utils.c; File 'main.c' Lines executed:100.00% of 22 Creating 'main.c.gcov' File 'utils.c' Lines executed:89.89% of 89 Creating 'utils.c.gcov' rm -rf temp.out ``` Не удалось достичь 100% покрытия кода. Рассмотрим вывод утилиты `gcov`. Не покрыты тестами только участки кода, отвечающие за проверку нулевых указателей и проверку на корректность передаваемых аргументов.