
- •Лабораторная работа №5
- •Описание строк
- •Можно ввести слова входной строки в отдельные строковые переменные:
- •Задача 5.1. Поиск подстроки
- •I. Исходные данные и результаты
- •III. Программа и тестовые примеры
- •I. Исходные данные и результаты
- •II. Алгоритм решения задачи
- •III. Программа и тестовые примеры
- •Задача 5.3. Вывод вопросительных предложений
- •I. Исходные данные и результаты
- •II. Алгоритм решения задачи
- •III. Программа и тестовые примеры
- •Контрольные вопросы
Задача 5.1. Поиск подстроки
Написать программу, которая определяет, встречается ли в заданном текстовом файле заданная последовательность символов. Длина строки текста не превышает 80 символов, текст не содержит переносов слов, последовательность не содержит пробельных символов.
На предыдущей лабораторной работе на примере задачи 4.3 мы рассмотрели общий порядок действий при создании программы. Будем придерживаться его и впредь.
I. Исходные данные и результаты
Исходные данные:
1. Текстовый файл неизвестного размера, состоящий из строк длиной не более 80 символов. Поскольку по условию переносы отсутствуют, можно ограничиться поиском заданной последовательности в каждой строке отдельно. Следовательно, необходимо помнить только одну текущую строку файла. Для ее хранения выделим строковую переменную длиной 81 символ (дополнительный символ требуется для завершающего нуля).
2. Последовательность символов для поиска, вводимая с клавиатуры. Поскольку по условию задачи она не содержит пробельных символов, ее длина также не должна быть более 80 символов, иначе поиск завершится неудачей. Для ее хранения также выделим строковую переменную длиной 81 символ.
Результатом работы программы является сообщение либо о наличии заданной последовательности, либо об ее отсутствии. Представим варианты сообщений в программе в виде строковых констант.
Для хранения длины строки будем использовать именованную константу. Для работы с файлом потребуется служебная переменная соответствующего типа.
П. Алгоритм решения задачи
Построчно считывать текст из файла.
Для каждой строки проверять, содержится ли в ней заданная последовательность.
Если да, напечатать сообщение о наличии заданной последовательности и завершить программу.
При нормальном выходе из цикла напечатать сообщение об отсутствии заданной последовательности и завершить программу.
III. Программа и тестовые примеры
#include <fstream.h>
#include <string.h>
int main()
{
const int len = 81; II 1
char word[len], line[len]; // 2
cout << “Введите слово для поиска: “; cin >> word;
ifstream fin(“text.txt”, ios::in | ios: :nocreate); // 3
if (!fin) { cout << “Ошибка открытия файла.” << endl;
return 1; } //4
while (fin.getline(line, len)) { // 5
if (strstr(line, word)) { // 6
cout << “Присутствует!” << endl; return 0; }
}
cout << “Отсутствует!” << endl;
return 0; // 7
}
Рассмотрим помеченные операторы. В операторе 1 описывается константа, определяющая длину строки файла и длину последовательности. В операторе 2 описывается переменная line для размещения очередной строки файла и переменная word для размещения искомой последовательности символов.
В операторе 3 определяется объект fin класса входных потоков ifstream. С этим объектом можно работать так же, как со стандартными объектами cin и cout, то есть использовать операции помещения в поток << и извлечения из потока <<, а также рассмотренные выше функции get, getline и другие. Предполагается, что файл с именем text.txt находится в том же каталоге, что и текст программы, иначе следует указать полный путь, дублируя символ обратной косой черты, так как иначе он будет иметь специальное значение, например:
ifstream fin(“c:\\prim\\cpp\\text.txt”, ios::in | ios::nocreate); // 3
В операторе 4 проверяется успешность создания объекта fin. Файлы, открываемые для чтения, проверять нужно обязательно! В операторе 5 организуется цикл чтения из файла в переменную line. Метод getline, описанный выше, при достижении конца файла вернет значение, завершающее цикл.
Для анализа строки в операторе 6 применяется функция strstr(line, word). Она выполняет поиск подстроки word в строке line. Обе строки должны завершаться нуль-символами. В случае успешного поиска функция возвращает указатель на найденную подстроку, в случае неудачи — NULL. Если вторым параметром передается указатель на строку нулевой длины, функция возвращает указатель на начало строки line.
В качестве тестового примера приготовьте текстовый файл, состоящий из нескольких строк5. Длина хотя бы одной из строк должна быть равна 80 символам. Для тестирования программы следует запустить ее по крайней мере два раза: введя с клавиатуры слово, содержащееся в файле, и слово, которого в нем нет.
Даже такую простую программу мы рекомендуем вводить и отлаживать по шагам. Это умение пригодится вам в дальнейшем. Предлагаемая последовательность отладки:
Ввести «скелет» программы (директивы #include, функцию main(), операторы 1-4). Добавить контрольный вывод введенного слова. Запустив программу, проверить ввод слова и успешность открытия файла. Выполнить программу, задав имя несуществующего файла, для проверки вывода сообщения об ошибке. Удалить контрольный вывод слова.
Проверить цикл чтения из файла: добавить оператор 5 с его завершающей фигурной скобкой, внутри цикла поставить контрольный вывод прочитанной строки:
cout << line << endl;
Удалить контрольный вывод строки.
3. Дополнить программу операторами проверки и вывода сообщений. Для полной проверки программы следует выполнить ее для нескольких последовательностей. Длина одной из них должна составлять максимально допустимую — 80 символов.
СОВЕТ: При вводе текста программы не ленитесь сразу же форматировать его и снабжать комментариями.
Задача 5.2. Подсчет количества вхождений слова в текст
Написать программу, которая определяет, сколько раз встретилось заданное слово в текстовом файле, длина строки в котором не превышает 80 символов. Текст не содержит переносов слов.
На первый взгляд эта программа не сильно отличается от предыдущей: вместо факта наличия искомой последовательности в файле требуется подсчитать количество вхождений слова, то есть после первого удачного поиска не выходить из цикла просмотра, а увеличить счетчик и продолжать просмотр. В целом это верно, однако в данной задаче нам требуется найти не просто последовательность символов, а законченное слово.
Определим слово как последовательность алфавитно-цифровых символов, после которых следует знак пунктуации, разделитель или признак конца строки. Слово может находиться либо в начале строки, либо после разделителя или знака пунктуации. Это можно записать следующим образом (фигурные скобки и вертикальная черта означают выбор из альтернатив):
слово =
{начало строки | знак пунктуации | разделитель}
символы, составляющие слово
{конец строки | знак пунктуации | разделитель}