УДК 004.424

ОСНОВЫ РАБОТЫ С КЛАССОМ STRING В С++ ДЛЯ УЧАЩИХСЯ

Дмитриев Владислав Леонидович1, Батыршин Артем Ильдарович2
1Стерлитамакский филиал Башкирского государственного университета, кандидат физико-математических наук, доцент кафедры прикладной информатики и программирования
2Стерлитамакский филиал Башкирского государственного университета, студент 3 курса факультета математики и информационных технологий

Аннотация
В работе приводится краткое изложение основ использования класса string в С++, необходимых для работы со строками. Отмечены некоторые моменты, связанные с выделением блоков памяти отдельными компиляторами С++. Приведен практический пример, демонстрирующий разделение строки на отдельные лексемы.

Ключевые слова: выделение памяти, класс, объект, программирование, строка символов


THE BASIC OF WORKING WITH THE STRING CLASS IN C++ FOR STUDENTS

Dmitriev Vladislav Leonidovich1, Batirshin Artem Ildarovich2
1Sterlitamak branch of the Bashkir state University, Ph.D. (Physics and Mathematics), associate Professor of the Department of applied informatics
2Sterlitamak branch of the Bashkir state University, 3rd year student of the faculty of mathematics and information technology

Abstract
The paper provides a summary of the basics of using the string class in C++ for work with strings. Highlighted some points related to the allocation of memory blocks separate C++ compilers. Presented practice example that demonstrates splitting a string into individual tokens.

Keywords: class, memory allocation, object, programming, string of character


Рубрика: 13.00.00 ПЕДАГОГИЧЕСКИЕ НАУКИ

Библиографическая ссылка на статью:
Дмитриев В.Л., Батыршин А.И. Основы работы с классом string в С++ для учащихся // Современные научные исследования и инновации. 2016. № 12 [Электронный ресурс]. URL: http://web.snauka.ru/issues/2016/12/74824 (дата обращения: 04.06.2017).

В настоящее время в большинстве школ нашей страны обучение программированию проводится на языке программирования Паскаль, причем наиболее часто используются компиляторы Pascal ABC и Free Pascal. Дело в том, что язык Паскаль изначально создавался для обучения, он использует простые конструкции, и очевидно, именно поэтому заслужил большую популярность.

Тем не менее, необходимо знакомить учащихся и с другими языками программирования, в частности, с языком С++. И если основные базовые конструкции в обоих языках сильно похожи, то при работе со строками имеются некоторые существенные отличия [1].

Строка в C++ представляет собой массив символов, оканчивающийся нулевым символом (”). Доступ к строке осуществляется, таким образом, через указатель на ее первый символ (значением строки является адрес ее первого символа).
Однако вместо применения символьных массивов, для хранения строк можно применять переменные типа string [1]. Такая возможность стала доступна после появления стандарта ISO/ANSI, который расширил библиотеку С++, добавив класс string. Он использует перегруженные операторы для поддержки string-объектов, о которых подробно рассказано в [2 – 4]. Ниже мы рассмотрим только некоторые основные моменты работы с данным классом.

Перед использованием класса string необходимо подключить заголовочный файл string, являющийся частью пространства имен std. Определение класса скрывает природу строки как массива символов, и позволяет рассматривать ее как обычную переменную. Тем не менее, во многих отношениях объект string можно использовать так же, как символьный массив:

  • объект string можно инициализировать строкой в стиле С;
  • можно использовать инструкции cin и cout;
  • можно использовать принцип доступа к элементам строки как к элементам массива (по индексу элемента).

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

string s1 = “Ivanov”, s2 = ” Alexandr”, s3;

s3 = s1 + s2;

cout<<s3;

Можно также использовать некоторые стандартные операции, например, такую как “+=“, а также операции сравнения (в том числе доступно сравнение строк string со строками в стиле языка C). При объявлении переменной типа string создается объект нулевой длины, однако при вводе (например, используя cin) программа автоматически увеличивает его.

Для определения длины строки (размера экземпляра объекта string) используется стандартная функция size(), которая, однако, является методом класса string, и потому указывается через точку после имени объекта (результат не включает завершающий нулевой символ):

string s = “programming language”;

int n = s.size(); // можно использовать s.length();

cout<<s;

Метод – это функция, которая может быть вызвана только объектом-экземпляром класса, в котором определен данный метод.

Класс string имеет несколько разновидностей конструкторов, что позволяет создавать объекты string разными способами. Так, например, при необходимости экземпляр объекта string можно заполнить необходимым количеством требуемых символов. Следующий конструктор создает объект string с именем s и заполняет строку 25 символами #:

string s(25, ‘#’);

Следующий конструктор создает объект string с именем s2, который является копией string-объекта s1:

string s2(s1);

Имеется также конструктор, который использует в качестве параметров строку в стиле языка C и целочисленное значение, которое указывает количество копируемых символов:

char a[]=”programming language”;

string s(a,11);

В этом случае при создании объекта s будут использованы первые 11 элементов массива a[ ].

При необходимости можно использовать только часть C-строки. Для этого нужно указать на начало и конец требуемого диапазона памяти, в которой хранится C-строка. Например:

char *a=”programming language”;

string s(a+3,a+10);

или так:

char a[]=”programming language”;

char *p=&a[0];

string s(p+3,p+10);

В обоих случаях результатом будет строка grammin. Конструктор класса string при таком формировании строки применяет значения элементов памяти в интервале [a+3, a+10), используя тот факт, что имя массива является указателем. Если же требуется инициализировать объект string частью строки другого объекта string, то нужно учесть, что имя объекта, в отличие от имени массива, не является адресом объекта. Поэтому следует поступить так (результат – всё та же строка grammin):

string a="programming language";

string s(&a[3],&a[10]);

При чтении строки, содержащей пробелы, на основе инструкции cin, возникают определенные сложности, т.к. пробел является признаком окончания ввода для cin. Поэтому для этого используется несколько другой синтаксис. Следующий код читает строку в объект string (при объявлении экземпляра объекта string используется конструктор по умолчанию, который создает пустую строку s):

string s;

getline(cin,s);

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

Существует несколько ограничений на длину строки:

  • максимально допустимая длина строки, задаваемая константой string::npos (обычно имеет тип unsigned int);
  • размер памяти, доступной программе.

Функция getline() для класса string будет читать данные из входного потока и сохранять их в строке до тех пор, пока не возникнет одна из следующих ситуаций:

  • Достигнут конец файла. В этом случае во входном потоке будет установлен флаг eofbit (признак достижения конца файла) и функции fail() и eof() будут возвращать значение true.
  • Во входном потоке встретился разделительный символ “n“. Этот символ удаляется из входного потока, но не сохраняется.
  • Прочитано максимально возможное количество символов (меньше значения константы string::npos и меньше количества доступных байт памяти). В таком случае во входном потоке устанавливается флаг failbit (ошибка чтения из потока), а функция fail() будет возвращать значение true.

Полезен также метод find() класса string, который позволяет найти позицию первого вхождения одной строки в другую (позиция первого символа):

string s1 = “programming language”, s2 = “amm”;

int n = s1.find(s2);

cout<<n; // результатом будет 5

Если строка не входит в исходную, то возвращается значение “-1″.

Для проверки строки на пустоту используется метод empty() класса string:

string s;

getline(cin, s);

if (s.empty()) cout<<”string is empty”; else

cout<<”string is not empty”;

Обменять содержимое двух строк можно на основе использования функции swap():

string s1 = “programming”, s2 = “language”;

cout<<s1<<” “<<s2<<endl;

swap(s1, s2);

cout<<s1<<” “<<s2;

Также в классе string имеется метод substr(), который возвращает строку, являющуюся подстрокой исходной строки, начиная с некоторой позиции pos и включая count символов (или до конца строки):

int pos = 5, count = 7;

string s1 = “programming language”, s2;

s2 = s1.substr(pos, count);

cout<<s2; // результат: amming

Замечание 1. К отдельным элементам строки можно обращаться по индексу. Однако для этих целей в классе string служит еще и метод at(), в который индекс элемента передается как аргумент. При этом данный метод обеспечивает проверку границ и генерирует исключение road_of_range, если обнаружена попытка обращения к несуществующему индексу.

Замечание 2. Большинство реализаций C++ выделяют для строки блок памяти больший, чем сама строка. Это делается для того, чтобы при добавлении очередного элемента строке было куда увеличиваться. Когда же строка увеличивается до размера блока, программа выделяет новый блок, вдвое больший, чем текущий размер строки. Такой подход уменьшает количество операций изменения размера, и достаточно эффективен. Размер текущего блока позволяет узнать метод capacity(), а запросить минимальный размер блока можно на основе метода reserve(). Ниже приводится пример, демонстрирующий только что сказанное (код написан для компиляторов Microsoft Visual C++ 2005 и выше).

#include “stdafx.h”

#include <iostream>

#include <string>

using namespace std;

int main()

{ setlocale(LC_ALL,”rus”);

string a=”programming language”, b=”word”, c;

cout<<”Текущие размеры строк:”<<endl;

cout<<a.size()<<”, “<<b.size()<<”, “<<c.size();

cout<<”nРезервы для строк:n”;

cout<<a.capacity()<<”, “<<b.capacity()<<”, ”

     <<c.capacity()<<endl;

cout<<”Резервы после b.reserve(35):n”;

b.reserve(35);

cout<<b.capacity()<<endl;

system(“pause”); return 0;}

Результат выполнения программы будет следующий:

Текущие размеры строк:

20, 4, 0

Резервы для строк:

31, 15, 15

Резервы после b.reserve(35):

47

Для продолжения нажмите любую клавишу . . .

Видно, что под строку в данном компиляторе резервируется минимум 15 байт, а при увеличении размера используется инкремент 16.

Компиляторы Borland C++ 5.02 и wxDev-C++ 7.4 при этом выделяют памяти ровно столько, сколько необходимо для размещения строки.

Рассмотрим теперь небольшой пример, наглядно показывающий работу со строками. В примере описывается функция, разделяющая введенную строку на отдельные лексемы (слова) и приведена работа с ней.

#include “stdafx.h”

#include <iostream>

#include <conio.h>

#include <string>

using namespace std;

void StrToWord (string c, string flag)

{int k,l=0,m; //flag содержит символы-разделители

int n1=(int)c.size(), n2=(int)flag.size();

string word;

bool t;

for(k=0; k<n1; k++)

{ t=false; //признак обнаружения символа-разделителя

for(m=0; m<n2; m++) if (c.at(k)==flag.at(m)) t=true;

if (!t) {word+=c.at(k); l++;} //не разделитель – формируем слово

if ( (t||k==n1-1) && l!=0) //иначе – выводим слово

{cout<<word<<endl; word.clear(); l=0;} } }

int main()

{ system(“cls”);

string s;

getline(cin,s);

StrToWord(s,” ,.”);

_getch(); return 0; }

Таким образом, работа со строками на основе использования класса string достаточно понятна и проста, и похожа на работу со строками в языке программирования Паскаль.


Библиографический список
  1. Дмитриев В.Л. Теория и практика программирования на С++. – Стерлитамак: РИО СФ БашГУ, 2013. – 308 с.
  2. Прата С. Язык программирования С++. Лекции и упражнения, 5-е изд.: Пер. с англ. – М.: Вильямс, 2007. – 1184 с.
  3. Страуструп Б. Язык программирования С++. Специальное издание. –  М.: Бином, 2004. – 1054 с.
  4. Stroustrup Bjarne. The C++ programming language / Bjarne Stroustrup. – Fourth edition. – Boston: Addison-Wesley, 2013. – 1368 p.


Все статьи автора «Дмитриев Владислав Леонидович»


© Если вы обнаружили нарушение авторских или смежных прав, пожалуйста, незамедлительно сообщите нам об этом по электронной почте или через форму обратной связи.

Связь с автором (комментарии/рецензии к статье)

Оставить комментарий

Вы должны авторизоваться, чтобы оставить комментарий.

Если Вы еще не зарегистрированы на сайте, то Вам необходимо зарегистрироваться: