Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lek12.doc
Скачиваний:
3
Добавлен:
15.11.2018
Размер:
124.42 Кб
Скачать

Лекция №12: Стандартный класс string

В лекции 11 вы познакомились со строками С и узнали, что это просто массивы символов, в которых конец строки отмечается символом ' \0'. При работе с такими строками необходимо учитывать их структуру. Скажем, если в конец строки нуж­но добавить символы, а в массиве для них недостаточно места, приходится созда­вать новый массив, вмещающий строки большей длины. Короче говоря, работая со строками С, нужно помнить об особенностях их реализации и хранения в памя­ти. Это является источником лишней работы и часто приводит к ошибкам. Стан­дарт C++ ANSI/ISO определяет, что в языке должен быть задан класс string, по­зволяющий работать со строками как с базовым типом данных и не заботиться о деталях его реализации. С этим типом данных вы сейчас и познакомитесь.

Первое знакомство с классом string

Класс string определен в библиотеке с именем <string> и отнесен к пространству имен std. Поэтому для его использования в программу нужно включить следую­щие директивы:

#include <string>

using namespace std;

Класс string позволяет работать со значениями и выражениями типа string почти так же, как со значениями простого типа данных. Так, для присваивания значе­ния переменной типа string можно пользоваться оператором =, а для конкатена­ции двух строк — оператором +. Предположим, что s1, s2 и s3 являются объектами типа string и переменные s1 и s2 содержат строковые значения. Тогда перемен­ной s3 можно присвоить строку, состоящую из s1, в конец которой добавлена строка s2, при помощи оператора:

s3 = s1 + s2;

выполняющего присваивание и конкатенацию.

И при этом нет риска, что s3 окажется слишком маленькой для нового значения. Если сумма значений длины строк si и s2 превысит вместимость переменной s3, для нее будет автоматически выделена дополнительная память.

Как отмечалось ранее в этой главе, заключенные в двойные кавычки строковые литералы в программе на C++ фактически являются строками С, и поэтому они не относятся к типу string. Но ими можно пользоваться как литеральными значе­ниями типа string, и мы часто будем говорить о них как о значениях типа string. Так, оператор

s3 = "Hello Mom!";

присваивает переменной s3 объект string, содержащий те же символы и в том же порядке, что и строка С "Hello Mom!".

У класса string имеется используемый по умолчанию конструктор, инициализи­рующий объект типа string пустой строкой. Кроме того, у него есть второй конст­руктор с одним аргументом, в котором задается стандартная строка С. Этот второй конструктор инициализирует объект типа string значением, представляющим ту же строку, что и аргумент. В качестве примера рассмотрим следующие две строки:

string phrase;

string noun("ants");

В первой из них объявляется строковая переменная phrase, инициализируемая пустой строкой. Во второй объявляется строковая переменная noun, которая ини­циализируется строкой, подобной строке С "ants". Большинство программистов скажут, что переменная noun инициализируется строкой "ants", но это неверно. На самом деле здесь имеет место приведение типов. Заключенная в кавычки стро­ка "ants" является строкой С, а не значением типа string. Переменной noun при­сваивается объект типа string, содержащий те же символы и в том же порядке, что и строка "ants", но его значение не завершается нуль-символом ' \0'. И теоре­тически программисту вообще не нужно знать, хранятся в нем строки в виде мас­сивов или в виде какой-нибудь другой структуры данных.

Существует альтернативный синтаксис объявления переменной типа string и вы­зова конструктора этого типа. Приведенные ниже две строки:

string noun("ants");

string noun = "ants";

являются эквивалентными.

Все эти особенности класса string демонстрирует маленькая программа, приве­денная в листинге 15.1. Обратите внимание, что значения типа string можно вы­водить с помощью оператора <<.

Листинг 15.1. Программа с использованием класса string

// Демонстрирует стандартный класс string. #include <iostream>

#include <string>

using namespace std;

Int main()

{

string phrase; // Инициализируется пустой строкой.

// Два способа инициализации строковой переменной.

string adjective("fried"), noun("ants");

string wish = "Bon appetite!";

phrase = "I love " + adjective + " " + noun + "!";

cout << phrase << endl << wish <<endl;

return 0; }

Пример диалога

I love fried ants!

Bon appetite!

Рассмотрим следующую строку из программы листинга 15.1:

phrase = "I love " + adjective + " " + noun + "!";

Для того чтобы программист мог выполнять конкатенацию строк таким простым и естественным способом, разработчикам языка C++ пришлось немало потру­диться. Строковая константа "I love " не является объектом типа string. Она хра­нится как строка С (в виде массива символов с нуль-терминатором). Встретив строку "I love " в качестве аргумента оператора +, C++ находит его перегруженное определение для таких значений как "I love ". Существует несколько подобных перегруженных версий этого оператора: со строкой С слева и объектом string справа, со строкой С справа и объектом типа string слева, со строками С с обеих сторон (также возвращающая объект string). И конечно, есть версия с двумя объ­ектами типа string.

На самом деле наличие такого количества перегруженных версий оператора кон­катенации в языке не обязательно. Если бы их не было, C++ просто вызывал бы конструктор класса string, преобразующий строку С "I love " в объект типа string, к которому можно применить оператор +. Это преобразование выполняет конст­руктор с одним строковым параметром. Но наличие полного набора перегружен­ных версий оператора + позволяет выполнять конкатенацию более эффективно.

Класс string

Класс string может использоваться для представления строк символов, причем более гибкого и эффективного, чем строки С.

Данный класс определен в библиотеке string, и это определение отнесено к простран­ству имен std. Поэтому программы, в которых он применяется, должны содержать сле­дующие (или эквивалентные им) директивы:

#include <string>

using namespace std;

У класса string имеется используемый по умолчанию конструктор, инициализирую­щий объект типа string пустой строкой, и конструктор, который принимает в качестве аргумента строку С и инициализирует объект типа string представленным ею значени­ем. Например:

string sis2("Hello");

После появления класса string некоторые программисты считают, что следует использовать только его. Однако на самом деле обойтись без строк С в програм­мах на C++ непросто.

Ввод-вывод с помощью класса string

Для вывода объектов типа string можно пользоваться оператором «, точно так же, как для вывода данных других типов. Эту простую операцию демонстрирует программа, приведенная в листинге 15.1. А вот в отношении ввода данных класса такого типа имеется одна тонкость.

Оператор ввода >> для объектов типа string работает так же, как для других дан­ных, но помните, что он игнорирует начальные пробелы и прекращает чтение, как только встретит символ пробела, табуляции или перевода строки. В качестве при­мера рассмотрим следующий код:

string s1, s2;

cin >> s1;

cin >> s2;

Если пользователь введет

May the hair on your toes grow long and curly!

объекту s1 будет присвоена строка "May" без ведущих и завершающих пробелов, а переменой s2 будет присвоена строка "the". To есть, оператор ввода позволяет счи­тывать только слова, но не строки, содержащие пробелы. Иногда именно это и тре­буется, но в общем случае считывания одних лишь слов недостаточно.

Если нужно, чтобы программа прочитала всю введенную пользователем строку в переменную типа string, можно воспользоваться функцией getline. Синтаксис ее использования со строковыми объектами несколько отличается от синтаксиса, описанного в лекции 14 для строк С. В частности, для ввода с клавиатуры не применяется вызов cin.getline, вместо этого вызывается функция getline (не яв­ляющаяся функцией-членом объекта cin) и объект cin передается ей в качестве аргумента.

string line;

cout << "Enter a line of input:\n";

getline(cin. line);

cout << line << "END OF OUTPUT\n";

Включив в состав завершенной программы этот код, можно получить следующий диалог:

Enter some input:

Do be do to you!

Do be do to you!END OF OUTPUT

Если в строке имеются ведущие или завершающие пробелы, они также становят­ся частью строкового значения, прочитанного функцией getline. Данная версия getline находится в библиотеке string. Вместо cin ей можно передавать потоко­вый объект, подключенный к текстовому файлу.

Ввод-вывод данных объектов типа string

Для вывода данных в объект типа string можно пользоваться оператором << и объек­том cout, а для ввода — оператором >> и объектом cin. Однако при использовании опе­ратора >> для ввода данных в объект типа string считывается только часть строки, ог­раниченная символами пробела, табуляции или перевода строки. Чтобы ввести всю строку с клавиатуры, можно применять функцию getline.

Примеры

string greeting("Hello"), response, next_word;

cout << greeting << endl;

getline(cin.response);

cin >> next_word;

Для чтения пустого символа нельзя использовать сin и >>.

Посимвольное чтение строки можно выполнить с помощью функции cin.get. Она считывает значения типа char, а не string, но может быть полезна для ввода дан­ных в объект string. В листинге 15.2 приведена программа, демонстрирующая ис­пользование функций getline и cin.get для ввода данных в объект типа string. Назначение функции newline объясняется в вопросе: одновременное использование потока cin с оператором >> и функции getline этой лекции.

Листинг 15.2. Программа, использующая класс string

// Демонстрирует использование функций getline и cin.get.

#include <iostream>

#include <string>

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]