- •Лабораторная работа № 7
- •Теоретические сведения
- •Описание переменных строкового типа
- •Инициализация переменных строкового типа
- •Инициализация массива строк
- •Ввод строки
- •Вывод строки
- •Доступ к компонентам строки
- •Выделение слов из строки
- •Формирование слова с помощью анализа компонентов строки
- •Формирование слова с помощью функции strtok
- •Формирование слова с помощью функции strpbrk
- •Примеры программирования
- •Контрольные вопросы
- •Варианты заданий
- •Функции работы со строками
- •Функции проверки символов
Лабораторная работа № 7
Программирование задач с использованием строк на языке С++
Цель работы: получить навыки программирования задач с использованием строкового типа данных на языке С++.
Теоретические сведения
Символьная строка (далее просто строка) является массивом типа char, который заканчивается нуль-символом ('\0').
Описание переменных строкового типа
Переменную строкового типа можно описать следующими способами:
как массив символов:
а) char имя_массива[n];
где n - количество символов в строке, включая завершающий нуль-символ. Например, char stroka[10];
или
б) char имя_массива[ ];
Например, char s[ ];
В описании а) для переменной stroka будет выделено 10 байтов памяти ЭВМ. В описании б) память выделена не будет. Это описание означает, что переменная s - это переменная строкового типа, длина которой не определена.
с использованием указателя на тип char. Например, char *stroka;
В данном описании память для переменной stroka не выделяется. Такое описание означает, что переменная stroka может содержать адрес ячейки памяти первого символа строки. Выделить память для переменной stroka можно с помощью функции new:
char *stroka=new char[20];
где 20 - это длина строки.
Инициализация переменных строкового типа
Задать значения переменным строкового типа можно с помощью строковых констант:
а) char stroka [10]="строка";
б) char stroka [ ]="строка";
В первом случае под переменную stroka отводится 10 байтов, но используются только первые 7 байтов (включая завершающий нуль-символ '\0').
Во втором случае переменная stroka занимает 7 байтов, т.е. для этой переменной память выделяется автоматически и ее размер определяется количеством символов строковой константы плюс завершающий нуль-символ.
Инициализация массива строк
Общий вид:
char имя_массива[n][m]={ строковая константа1,
строковая константа2,
. . .
строковая константаn};
где n - количество элементов массива, т.е. количество строк; m - длина строки.
Пример 7.1.
сhar mas_words [10][80];
сhar mas_words [3][10] ={"первое",
"второе",
"третье"};
Ввод строки
Операция >> вводит строку из (MAX_LEN-1) символов, не содержащую пробелов. Значащих символов в строке может быть не более, чем (MAX_LEN-1), так как строка обязательно содержит завершающий нулевой байт '\0', который служит признаком завершения строки. Особенность операции >> состоит в том, что пробел она воспринимает как нулевой символ, то есть как признак конца строки.
Если строка содержит пробелы, то для ее считывания используется метод класса istream cin.get(). Мы пока не будем останавливаться на подробностях использования методов классов - речь об этом пойдет в соответствующем разделе, связанном с объектно-ориентированным программированием. Для работы со строками достаточно знать, что оператор
cin.get(str,MAX_LEN);
позволяет ввести с клавиатуры строку str, не превышающую (MAX_LEN-1) символов.
Пример 7.2. Ввод строки, содержащей пробелы.
#include <iostream>
using namespace std;
int main()
{ const int MAX_LEN = 80; // максимальная длина строки
char str[MAX_LEN];
cout << "Введите строку: ";
cin.get(str,MAX_LEN);
cout << "Введенная строка:" << str << endl;
return 0;
}
Для ввода строки можно также воспользоваться методом getline.
Пример 7.3. Ввод строки, содержащей пробелы.
#include <iostream>
using namespace std;
int main()
{ const int MAX_LEN = 80; // максимальная длина строки
char str[MAX_LEN];
cout << "Введите строку: ";
cin.getline(str,MAX_LEN);
cout << "Введенная строка:" << str << endl;
return 0;
}
Методы работают почти одинаково. Различие состоит в том, что метод getline считывает из входного потока не более (MAX_LEN-1) символов и записывает их в указанную строковую переменную, заменяя символ перевода строки \n нулевым байтом. Символ перевода строки при этом из потока удаляется.
Метод get оставляет символ перевода строки в потоке. Поэтому при попытке ввода нескольких строк, как показано в примере 7.4, будет введена лишь первая строка. Вместо всех остальных окажутся пустые строки, так как символ \n, оставленный в потоке методом get при вводе первой строки, будет обнаружен следующим методом get и интерпретируется как ввод пустой строки. При этом сам символ \n так и остается в потоке.
Пример 7.4. Попытка ввода нескольких строк.
#include <iostream>
using namespace std;
int main()
{ const int MAX_LEN = 80; // максимальная длина строки
char str[MAX_LEN];
cout << "Введите строку: ";
cin.get(str,MAX_LEN);
cout << "Введенная строка:" << str << endl;
cout << "Введите строку: ";
cin.get(str,MAX_LEN);
cout << "Введенная строка:" << str << endl; // пустая строка
cout << "Введите строку: ";
cin.get(str,MAX_LEN);
cout << "Введенная строка:" << str << endl; // пустая строка
return 0;
}
Удаление символа \n из потока может быть осуществлено вызовом метода get() без параметров.
Пример 7.5. Ввод нескольких строк.
#include <iostream>
using namespace std;
int main()
{ const int MAX_LEN = 80; // максимальная длина строки
char str[MAX_LEN];
cout << "Введите строку: ";
cin.get(str,MAX_LEN);
cout << "Введенная строка:" << str << endl; //вывод
//введенной строки
cin.get();
cout << "Введите строку: ";
cin.get(str,MAX_LEN);
cout << "Введенная строка:" << str << endl; //пустая строка
cin.get();
cout << "Введите строку: ";
cin.get(str,MAX_LEN);
cout << "Введенная строка:" << str << endl; //пустая строка
cin.get();
return 0;
}
Однако, можно в примере 7.4 воспользоваться методом getline вместо метода get. Тогда эффекта потери строк не возникает, и нет необходимости специально удалять символ \n из потока.
Современные версии языка С++ позволяют вводить несколько строк, пользуясь методом get с тремя аргументами: имя строковой переменной, длина строки и символ завершения ввода. Тогда символ перевода строки не будет служить признаком завершения ввода строки. Теперь строки можно вводить до тех пор, пока не будет введен символ, объявленный признаком завершения ввода, или пока не будет превышен максимальный размер строки.
Пример 7.6. Ввод нескольких строк.
#include <iostream>
using namespace std;
int main()
{ const int MAX_LEN = 180; // максимальная длина строки
char str[MAX_LEN];
cout << "Введите строку: ";
cin.get(str,MAX_LEN,'*');
cout << "Введенная строка:" << str << endl;
return 0;
}
В результате получится:
Введите строку: Якорь выбран чугунный И в открытых лагунах Наши старые шхуны Снова лижет прибой. * |
Введенная строка: Якорь выбран чугунный И в открытых лагунах Наши старые шхуны Снова лижет прибой.
|
Ввод строки можно осуществить также с помощью функции gets (char *). Эта функция читает строку со стандартного устройства ввода (клавиатуры) до тех пор, пока не встретится символ новой строки ('\n'). Функция считывает все символы до символа новой строки и присоединяет нуль-символ в конец строки.
Пример 7.7.
char str [80];
gets (str);
char * stroka = new char [20];
gets (stroka);
Ввести строку можно и c помощью функции scanf с использованием формата “%s”, но эта функция считывает символы до символа разделителя (пробел, табуляция, переход на новую строку) или по количеству символов в спецификации формата (%10s). Это очень неудобно, так как практически всегда требуется вводить строку с символами-разделителями. Поэтому функция scanf менее предпочтительна.