Лекция 8. Строки. std::basic_string

Содержание

Слайд 2

Работа с символами.

cout << "Hello, World!\n"
Строка - это последовательность символов, заключенная

Работа с символами. cout Строка - это последовательность символов, заключенная в двойные
в двойные кавычки. Два символа: обратной дробной черты \ и непосредственно следующий за ним - обозначают некоторый специальный символ. В данном случае \n является символом конца строки (или перевода строки), поэтому он выдается после символов Hello, world!
Каждая строка содержит на один символ больше, чем явно задано: все строки оканчиваются нулевым символом ('\0'), имеющим значение 0. Поэтому
sizeof("asdf")==5;
Типом строки считается "массив из соответствующего числа символов", поэтому тип "asdf" есть char[5]. Пустая строка записывается как "" и имеет тип char[1]. Отметим, что для любой строки s выполняется strlen(s)==sizeof(s)-1, поскольку функция strlen() не учитывает завершающий символ '\0'.
Внутри строки можно использовать для представления невидимых символов специальные комбинации с \. В частности, в строке можно задать сам символ двойной кавычки " или символ \. Чаще всего из таких символов оказывается нужным символ конца строки '\n‘.

Слайд 3

Для большей наглядности программы длинные строки можно разбивать пробелами, например:
char alpha[ ]

Для большей наглядности программы длинные строки можно разбивать пробелами, например: char alpha[
= "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Подобные, подряд идущие, строки будут объединяться в одну, поэтому массив alpha можно эквивалентным образом инициализировать с помощью одной строки:
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
В строке можно задавать символ '\0', но большинство программ не ожидает после него встречи с какими-либо еще символами. Например, строку "asdf\000hjkl" стандартные функции strcpy() и strlen() будут рассматривать как строку "asdf".

Слайд 4

Строки в STL

Класс string из стандартной библиотеки представляет собой специализацию общего шаблонного

Строки в STL Класс string из стандартной библиотеки представляет собой специализацию общего
класса basic_string для символьного типа char; иначе говоря, объект string это последовательность переменных типа char.

typedef basic_string, allocator > string;
typedef basic_string, allocator > wstring;

template<> struct char_traits
template<> struct char_traits

template
struct char_traits : public _Char_traits<_Elem, long>
{ // properties of a string or stream unknown element
};

template < class _Elem, class _Int_type >
struct _Char_traits
// properties of a string or stream element

template
class allocator : public _Allocator_base<_Ty>
// generic allocator for objects of class _Ty

template
struct _Allocator_base
{
typedef _Ty value_type;
};

Слайд 5

Характеристические классы

Характеристический шаблонный класс определяет протокол описания типа, а специализации этого класса

Характеристические классы Характеристический шаблонный класс определяет протокол описания типа, а специализации этого
описывают конкретный тип. Частичные специализации описывают множество типов, обладающих общими характеристиками.
Некоторые характеристические классы предназначены для распознавания свойств типов, на основе которых они определяют собственные переменные-члены и типы-члены.
Большинство характеристических классов предоставляют информацию о типе или значении и специализированную функциональность.

static int compare(
_In_reads_(_Count) const _Elem *_First1,
_In_reads_(_Count) const _Elem *_First2, size_t _Count)
static size_t length(_In_z_ const _Elem *_First)
// find length of null-terminated sequence
static _Elem *copy (…)

Слайд 6

template
class basic_string : public _String_alloc
< !is_empty<_Alloc>::value,

template class basic_string : public _String_alloc ::value, _String_base_types > // null-terminated transparent
_String_base_types<_Elem, _Alloc> >
// null-terminated transparent array of elements
template< bool _Al_has_storage, class _Alloc_types>
class _String_alloc : public _String_val
< typename _Alloc_types::_Val_types>
// base class for basic_string to hold allocator with storage
template
class _String_val
: public _Container_base
// base class for basic_string to hold data

Слайд 7

Конструкторы

explicit basic_string (1) (const allocator_type& alloc = allocator_type());
Конструирует пустую строку.
copy (2) Создает копию
basic_string

Конструкторы explicit basic_string (1) (const allocator_type& alloc = allocator_type()); Конструирует пустую строку.
(const basic_string& str);
substring (3) конструктор подстроки: Копирует часть строки str, которая начинается в позиции символа pos
basic_string (const basic_string& str, size_type pos, size_type len = npos, const allocator_type& alloc = allocator_type());
from c-string (4) Копирует символьную последовательность (C-строку), указанную символом s
basic_string (const charT* s, const allocator_type& alloc = allocator_type());
from sequence (5) Копирует первые n символов из массива символов, на которые указывает s
basic_string (const charT* s, size_type n, const allocator_type& alloc = allocator_type());

Слайд 8

Конструкторы

fill (6) Заполняет строку n последовательными копиями символа c
basic_string (size_type n, charT

Конструкторы fill (6) Заполняет строку n последовательными копиями символа c basic_string (size_type
c, const allocator_type& alloc = allocator_type());
range (7) Копирует последовательность символов в диапазоне [первый, последний) в том же порядке.
template
basic_string (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type());
(8) Копирует каждый из символов в il, в том же порядке.
basic_string (initializer_list il, const allocator_type& alloc = allocator_type());
(9) перемещающие конструкторы
basic_string (basic_string&& str) noexcept;
basic_string (basic_string&& str, const allocator_type& alloc);

Слайд 9

Примеры

#include
#include
int main () {
std::string s0 ("Initial string");
// конструкторы

Примеры #include #include int main () { std::string s0 ("Initial string"); //
используются в том же порядке, как описано выше:
std::string s1;
std::string s2 (s0);
std::string s3 (s0, 8, 3);
std::string s4 ("A character sequence", 6);
std::string s5 ("Another character sequence");
std::string s6 (10, 'x');
std::string s7a (10, 42);
std::string s7b (s0.begin(), s0.begin()+7);
std::cout << "s1: " << s1 << "\ns2: " << s2 << "\ns3: " << s3;
std::cout << "\ns4: " << s4 << "\ns5: " << s5 << "\ns6: " << s6;
std::cout << "\ns7a: " << s7a << "\ns7b: " << s7b << '\n';
return 0;
}

s1:
s2: Initial string
s3: str
s4: A char
s5: Another character sequence
s6: xxxxxxxxxx
s7a: **********
s7b: Initial

Слайд 10

Операции со строками

s1 = s2 Присвоение строки s2 строке s1; строка s2

Операции со строками s1 = s2 Присвоение строки s2 строке s1; строка
может быть объектом
класса string или строкой к стиле языка С
s += s1 Добавление объекта s1 в конец строки; объект s1 может быть символом, объектом класса string или строкой в стиле языка С
s[i] Индексация ( как у обычного массива)
s = s1+s2 Конкатенация; символы в целевом объекте класса string будут копиями символов их строки s1, за которыми следуют копии символов из строки s2
s1==s2 Сравнение объектов класса string; либо s1, либо s2, но не оба
объекта могут быть строкой в стиле языка С.
s1 != s2 Проверка неравенства объектов s1 и s2
s1 < s2 Лексикографическое сравнение объектов класса string; либо s1, либо s2, но не оба объекта могут быть строкой в стиле языка С.
. <=, > и >= Аналогично.

Слайд 11

s.size () Количество символов в строке s
s.length () Количество символов в строке s
s.c_str

s.size () Количество символов в строке s s.length () Количество символов в
() Преобразование в строку в стиле языка С
s.begin () Итератор на первый символ
s.end() Итератор ячейки, следующей за концом строки s
s.insert( pos, x) Вставка объекта х перед строкой s [pos]; объект х может быть символом, объектом класса string или строкой в стиле языка С. Строка s увеличивается, чтобы поместить символы из объекта х
s.append( x ) Вставка объекта х в конец строки s ;
Строка s увеличивается, чтобы поместить символы из объекта х
s.erase( pos ) Удаление символа из позиции s [pos].
Размер строки s уменьшается на единицу
pos = s.find( x) Поиск объекта х в строке s; переменная pos —
это индекс первого найденного символа или значение npos (позиция
ячейки, следующей за концом строки s
In >> s Считывание слова, отделенного пробелами из потока in в объект s
getline( in, s) Считывание строки текста из потока in в объект s
out << s Запись данных из объекта s в поток out

Слайд 12

Операции insert и append перемещают символы, чтобы освободить место для новых.

Операция

Операции insert и append перемещают символы, чтобы освободить место для новых. Операция
erase (pos) сдвигает символы влево, чтобы заполнить пробел, оставшийся после удаления символа

Слайд 13

Примеры: append

#include
#include
using namespace std;
int main () {
string str;
string

Примеры: append #include #include using namespace std; int main () { string
str2="Writing ";
string str3="print 10 and then 5 more";
// used in the same order as described above:
str.append(str2); // "Writing "
str.append(str3,6,3); // "10 "
str.append("dots are cool",5); // "dots "
str.append("here: "); // "here: "
str.append(10u,'.'); // ".........."
str.append(str3.begin()+8,str3.end()); // " and then 5 more"
str.append (5,0x2E); // "....."
cout << str << '\n';
} Output: Writing 10 dots here: .......... and then 5 more.....

Слайд 14

Примеры: insert

void ins(){
string str="to be question";
string str2="the ";
string str3="or

Примеры: insert void ins(){ string str="to be question"; string str2="the "; string
not to be";
string::iterator it;
str.insert(6,str2); // to be (the )question
str.insert(6,str3,3,4); // to be (not )the question
str.insert(10,"that is cool",8); // to be not (that is )the question
str.insert(10,"to be "); // to be not (to be )that is the question
str.insert(15,1,':'); // to be not to be(:) that is the question
it = str.insert(str.begin()+5,','); // to be(,) not to be: that is the question
str.insert (str.end(),3,'.'); // to be, not to be: that is the question(...)
str.insert (it+2,str3.begin(),str3.begin()+3); // (or )
std::cout << str << '\n';
} Output: to be, or not to be: that is the question...

Слайд 15

Преобразования
stoi - Преобразовать строку в целое число
stol - Конвертировать строку в

Преобразования stoi - Преобразовать строку в целое число stol - Конвертировать строку
long int
stoul - Преобразовать строку в целое число без знака
stoll - Конвертировать строку в long long
stoull - Convert string to unsigned long long
stof - Преобразование строки в float
stod - Преобразование строки в double
stold - Преобразование строки в long double

Слайд 16

Итераторы basic_string
begin - Возвратить итератор к началу
end - Возвратить итератор к

Итераторы basic_string begin - Возвратить итератор к началу end - Возвратить итератор
концу
rbegin - Возвратить обратный итератор к обратному началу
rend - Возвратить обратный итератор к обратному концу
cbegin
Return const_iterator to beginning
cend
Return const_iterator to end
crbegin
Return const_reverse_iterator to reverse beginning
crend
Return const_reverse_iterator to reverse end

Слайд 17

Пример: Итераторы basic_string

// string::begin/end
#include
#include
int main ()
{
std::string str ("Test

Пример: Итераторы basic_string // string::begin/end #include #include int main () { std::string
string");
for ( std::string::iterator it=str.begin(); it!=str.end(); ++it)
std::cout << *it;
std::cout << '\n';
return 0;
}}

Output:
Test string

Слайд 18

Пример: Итераторы basic_string

// string::rbegin/rend
#include
#include
int main ()
{
std::string str ("now

Пример: Итераторы basic_string // string::rbegin/rend #include #include int main () { std::string
step live...");
for (std::string::reverse_iterator rit=str.rbegin(); rit!=str.rend(); ++rit)
std::cout << *rit;
return 0;
}

Output:
...evil pets won

Слайд 19

basic_string::operator=
string (1)
basic_string& operator= (const basic_string& str);
c-string (2)
basic_string& operator= (const charT* s);
character (3)
basic_string&

basic_string::operator= string (1) basic_string& operator= (const basic_string& str); c-string (2) basic_string& operator=
operator= (charT c);
initializer list (4)
basic_string& operator= (initializer_list il);
move (5)
basic_string& operator= (basic_string&& str) noexcept;

Слайд 20

Пример: operator=

#include
#include
int main ()
{
std::string str1, str2, str3;
str1

Пример: operator= #include #include int main () { std::string str1, str2, str3;
= "Test string: "; // c-string
str2 = 'x'; // single character
str3 = str1 + str2; // string
std::cout << str3 << '\n';
return 0;
}

Output:
Test string: x

Слайд 21

basic_string::operator[ ]
reference operator[ ] (size_type pos);
const_reference operator[ ] (size_type pos) const;
#include

basic_string::operator[ ] reference operator[ ] (size_type pos); const_reference operator[ ] (size_type pos)

#include
int main () {
std::string str ("Test string");
for (int i=0; i std::cout << str[i];
}
return 0;
}

Слайд 22

Потоки строк

Объект класса string можно использовать в качестве источника ввода для

Потоки строк Объект класса string можно использовать в качестве источника ввода для
потока istream или цели вывода для потока ostream. Поток istream, считывающий данные из объекта класса string, называется istringstream, а поток ostream, записывающий символы в объект класса string, называется ostringstream. Например, поток istringstream полезен для извлечения числовых значений из строк.

stringstream ss;
ss << "22.84";
float k = 0;
ss >> k;

Слайд 23

#include
#include
#include
using namespace std;
void error( char* e, const char* s){
cerr<

#include #include #include using namespace std; void error( char* e, const char*
"<}
double str_to_double(string s){
istringstream is (s); // создаем поток для ввода из строки s
double d;
is >> d;
if (! is) error("ошибка форматирования типа double ",s.c_str());
return d;
}

Слайд 24

void func_out( string label, double d) {
ostringstream os; // поток

void func_out( string label, double d) { ostringstream os; // поток для
для составления сообщения
os << setw(8) << label << ": "
<< fixed << setprecision (10)
<< d ;
cout<}
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL, "Russian");
string s;
double d1 = str_to_double("12.4");
double d2 = str_to_double("1.34e-3");
double d3 = str_to_double("ha-ha-ha"); // вызывается error()
func_out("test", d1) ;
return 0;
}

Слайд 25

Содержание строко- потоковых классов

typedef basic_istringstream,
allocator > istringstream;
templateclass _Traits,
class _Alloc>
class basic_istringstream
:

Содержание строко- потоковых классов typedef basic_istringstream , allocator > istringstream; template class
public basic_istream<_Elem, _Traits>
// input stream associated with a character array
templateclass _Traits>
class basic_istream
: virtual public basic_ios<_Elem, _Traits>
// control extractions from a stream buffer

Слайд 26

templateclass _Traits>
class basic_ios
: public ios_base
// base class for basic_istream/basic_ostream
class ios_base
: public

template class _Traits> class basic_ios : public ios_base // base class for
_Iosb
// base class for ios
template class _Iosb
// define templatized bitmask / enumerated types, instantiate on demand

Слайд 27

Реализация операций string

string s="test";
const char* cc= s.c_str();
///////////////////////////////////
const _Elem *c_str() const
{// return

Реализация операций string string s="test"; const char* cc= s.c_str(); /////////////////////////////////// const _Elem
pointer to null-terminated nonmutable array
return (this-> _Myptr());
}
const value_type * _Myptr() const
{// determine current pointer to buffer for nonmutable string
return (this->_BUF_SIZE <= this->_Myres
? _STD addressof(*this->_Bx._Ptr)
: this->_Bx._Buf);
}
union _Bxty
{// storage for small buffer or pointer to larger one
value_type _Buf[_BUF_SIZE];
pointer _Ptr;
char _Alias[_BUF_SIZE];// to permit aliasing
} _Bx;

Слайд 28

Примеры: substr и find

void sub(){
std::string str="We think in generalities, but we

Примеры: substr и find void sub(){ std::string str="We think in generalities, but
live in details.";
// (quoting Alfred N. Whitehead)
std::string str2 = str.substr (3,5); // "think"
std::size_t pos = str.find("live"); // position of "live" in str
std::string str3 = str.substr (pos); // get from "live" to the end
std::cout << str2 << ' ' << str3 << '\n';
}
Output: think live in details.

Слайд 29

Примеры: replace

void repl(){
string base="this is a test string.";
string str2="n example";

Примеры: replace void repl(){ string base="this is a test string."; string str2="n
string str3="sample phrase";
string str4="useful.";
string str=base; // "this is a test string."
str.replace(9,5,str2); // "this is an example string." (1)
str.replace(19,6,str3,7,6); // "this is an example phrase." (2)
str.replace(8,10,"just a"); // "this is just a phrase." (3)
str.replace(8,6,"a shorty",7); // "this is a short phrase." (4)
str.replace(22,1,3,'!'); // "this is a short phrase!!!" (5)
str.replace(str.begin(),str.end()-3,str3); // "sample phrase!!!" (1)
str.replace(str.begin(),str.begin()+6,"replace"); // "replace phrase!!!" (3)
str.replace(str.begin()+8,str.begin()+14,"is coolness",7); // "replace is coo" (4)
str.replace(str.begin()+12,str.end()-4,4,'o'); // "replace is cooool!!!" (5)
str.replace(str.begin()+11,str.end(),str4.begin(),str4.end());// "replace is useful." (6)
cout << str << '\n';
}
Output: replace is useful.

Слайд 30

Примеры: erase

void erase(){
string str ("This is an example sentence.");
cout <<

Примеры: erase void erase(){ string str ("This is an example sentence."); cout
str << '\n'; // "This is an example sentence."
str.erase (10,8); // ^^^^^^^^
cout << str << '\n'; // "This is an sentence."
str.erase (str.begin()+9); // ^
cout << str << '\n'; // "This is a sentence."
str.erase (str.begin()+5, str.end()-9); // ^^^^^
cout << str << '\n';
}
Output:
This is an example sentence.
This is an sentence.
This is a sentence.
This sentence..

Слайд 31

Широкие строки

typedef basic_string < wchar_t > wstring;
wstring ws = L"Super";
Символы, которые

Широкие строки typedef basic_string wstring; wstring ws = L"Super"; Символы, которые могут
могут содержаться в строке, не ограничены типом wchar_t . В действительности символы могут быть практически любым типом без конструктора, для которого можно определить свойства символов.
Свойства символов определяют различные характеристики символов, включая их порядок для сравнения, метод завершения последовательностей, а также как копировать и перемещать диапазоны символов.
Это обеспечивает высокую гибкость представления символов, включая типы многобайтных символов, использующиеся в международных наборах символов.

Слайд 32

Пример

#include
#include
#include
#include
#include
using namespace std;
int main() {
_setmode(_fileno(stdout),

Пример #include #include #include #include #include using namespace std; int main() {
_O_U16TEXT); // переключаем на юникод
std::wcout.clear(); // очистка потока
std::wstring s(L"Проверка\n");
wcout << s;
std::vector v(s.length());
for (size_t idx = 0; idx < s.length(); idx++)
v[idx] = s[idx]; // посимвольно копируем в вектор целых
std::basic_string ss (v.begin(), v.end()); // создаем новую строку
// юникод-символов, передавая диапазон вектора

Слайд 33

for (int i : v)
wcout << i << " ";

for (int i : v) wcout wcout for ( wchar_t i :
// вывод значений вектора целых
wcout << endl;
for ( wchar_t i : ss)
wcout << i << " "; // вывод юникод-строки посимвольно
wcout << endl;
wcout << ss; // вывод юникод-строки
_setmode(_fileno(stdout), _O_TEXT); // переключение на обычный текст
cout<< 22<< endl;
cout<< "GGG проверка GGG"<< endl;;
return 0;
}

Слайд 34

Пример. Преобразование.

#include
#include
#include
#include
#include
std::wstring wide_string ( std::string const&

Пример. Преобразование. #include #include #include #include #include std::wstring wide_string ( std::string const&
s, std::locale const& loc )
{ // из string в wstring
if (s.empty()) return std::wstring();
std::ctype const& facet = std::use_facet >(loc);
char const* first = s.c_str();
char const* last = first + s.size();
std::vector result(s.size());
facet.widen(first, last, &result[0]);
return std::wstring(result.begin(), result.end());
}

Слайд 35

std::string narrow_string( std::wstring const& s,
std::locale const& loc, char default_char =

std::string narrow_string( std::wstring const& s, std::locale const& loc, char default_char = '?')
'?')
{
// из wstring в string
if (s.empty()) return std::string();
std::ctype const& facet = std::use_facet >(loc);
wchar_t const* first = s.c_str();
wchar_t const* last = first + s.size();
std::vector result(s.size());
facet.narrow(first, last, default_char, &result[0]);
return std::string(result.begin(), result.end());
}

Слайд 36

char const *russian_locale_designator = "rus";
int main() {
std::locale loc(russian_locale_designator);
std::wstring const

char const *russian_locale_designator = "rus"; int main() { std::locale loc(russian_locale_designator); std::wstring const
s = L"русский текст";
std::string const sa = ::narrow_string(s, loc);
std::wstring const sw = ::wide_string(sa, loc);
std::locale::global ( loc );
std::wcout << "original wide: " << s << std::endl;
std::cout << "wide -> narrow: " << sa << std::endl;
std::wcout << "narrow -> wide: " << sw << std::endl;
return 1;
}
Вывод : original wide: русский текст
wide -> narrow: русский текст
narrow -> wide: русский текст

Слайд 37

Еще один опыт.

using int_string = std::basic_string< int, std::char_traits, std::allocator >;
void add_to_int_str(int

Еще один опыт. using int_string = std::basic_string , std::allocator >; void add_to_int_str(int
n) {
int_string si;
si.resize(n);
for (int i = 0; i < n; i++) {
si[i] = i;
}
}
void add_to_vec(int n) {
vector v;
v.resize(n);
for (int i = 0; i < n; i++) {
v[i] = i;
}
}

Слайд 38

Продолжение …

#include
#include
#include
using namespace concurrency;
template
__int64 time_call(Function&&

Продолжение … #include #include #include using namespace concurrency; template __int64 time_call(Function&& f)
f) {
__int64 begin = GetTickCount();
f();
return GetTickCount() - begin;
}
#define Print for (auto& i : si) cout << i << " "; cout << endl;

Слайд 39

Продолжение …

void main() {
// typedef std::basic_string< int, std::char_traits,

Продолжение … void main() { // typedef std::basic_string , // std::allocator >
// std::allocator > int_string ;
int_string si ; si.append(2, 3); Print
si.append({ 4,1 }); Print
int sz = si.size(); Print
si = si.substr(1, 2); Print
si += 55; Print
si.insert(1, 5, 10); Print
si.insert(4, si); Print
si.erase(11); Print
Вывод: 3 3
3 3 4 1
3 3 4 1
3 4
3 4 55
3 10 10 10 10 10 4 55
3 10 10 10 3 10 10 10 10 10 4 55 10 10 4 55
3 10 10 10 3 10 10 10 10 10 4
Имя файла: Лекция-8.-Строки.-std::basic_string.pptx
Количество просмотров: 23
Количество скачиваний: 0