Урок №205. добавление к std

Обзор классов строк

Весь строковый функционал стандартной библиотеки находится в заголовочном файле. Чтобы использовать его, просто включите заголовок :

На самом деле в заголовке есть 3 разных класса строк. Первый – это шаблонный базовый класс с именем :

Вы не будете работать с этим классом напрямую, поэтому пока не беспокойтесь о том, что это за и . Значений по умолчанию будет достаточно почти во всех мыслимых случаях.

Стандартная библиотека предоставляет две разновидности :

Это два класса, которые вы непосредственно будете использовать. используется для стандартных строк ASCII и UTF-8. используется для строк с расширенными символами / Unicode (UTF-16). Для строк UTF-32 нет встроенного класса (хотя вы можете расширить из свой собственный класс, если он вам нужен).

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

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

Функция Действие
Создание и уничтожение
конструктор Создает или копирует строку
деструктор Уничтожает строку
Размер и вместимость
Возвращает количество символов, которые могут храниться без перераспределения памяти
Возвращает логическое значение, указывающее, пуста ли строка
, Возвращает количество символов в строке
Возвращает максимальный размер строки, которая может быть размещена
Увеличить или уменьшить вместимость строки
Доступ к элементам
, Доступ к символу по определенному индексу
Модификация
, Присваивает новое значение строке
, , Добавляет символы в конец строки
Вставляет символы в строку по произвольному индексу
Удаляет все символы в строке
Стирает символы по произвольному индексу в строке
Заменяет символы с произвольным индексом на другие символы
Расширение или сжатие строки (обрезает или добавляет символы в конце строки)
Меняет местами значения двух строк
Ввод и вывод
, Считывает значения из входного потока в строку
Записывает значение строки в выходной поток
Возвращает содержимое строки как строку в стиле C с завершающим нулем
Копирует содержимое (не оканчивающееся нулем) в массив символов
То же, что . Неконстантная перегрузка позволяет выполнять запись в возвращаемую строку
Сравнение строк
, Сравнивает, равны или неравны две строки (возвращает )
, , , Сравнивает, являются ли две строки меньше/больше друг друга (возвращает )
Сравнивает, равны или неравны две строки (возвращает -1, 0 или 1)
Подстроки и конкатенация
Объединяет две строки
Возвращает подстроку
Поиск
Найти индекс первого символа/подстроки
Найти индекс первого символа из набора символов
Найти индекс первого символа, не входящего в набор символов
Найти индекс последнего символа из набора символов
Найти индекс последнего символа, не входящего в набор символов
Найти индекс последнего символа/подстроки
Поддержка итераторов и распределителей памяти (аллокаторов)
, Поддержка итератора прямого направления для начала/конца строки
Возвращает распределитель
, Поддержка итератора обратного направления для начала/конца строки

Хотя строковые классы библиотеки STL предоставляют множество функций, есть несколько заметных упущений:

  • поддержка регулярных выражений;
  • конструкторы для создания строк из чисел;
  • функции изменения регистра на верхний/нижний;
  • сравнение без учета регистра;
  • разбиение строки на массив;
  • простые функции для получения левой или правой части строки;
  • обрезка пробелов в начале и конце строки;
  • форматирование строки в стиле ;
  • преобразование из UTF-8 в UTF-16 или наоборот.

Для большинства из них вам придется либо написать свои собственные функции, либо преобразовать вашу строку в строку в стиле C (используя ) и использовать функции C, которые предлагают эту функциональность.

В следующих уроках мы более подробно рассмотрим различные функции класса . Хотя в наших примерах мы будем использовать , всё в равной степени применимо и к .

string& string::insert(size_type index, const string& str, size_type startindex, size_type num)

   Эта функция вставляет с определенного std::string указанное количество символов () строки , начиная со -а.

   Возвращает скрытый указатель *this, что позволяет «связывать» объекты.

   Генерирует исключение out_of_range, если или некорректны.

   Генерирует исключение length_error, если результат превышает максимально допустимое количество символов.

Например:

#include <iostream>
#include <string>

int main()
{
std::string sString(«bbb»);

const std::string sInsert(«012345»);
sString.insert(1, sInsert, 2, 4); // вставляем подстроку sInsert длиной 4, начиная с символа под индексом 2, в строку sString, начиная с индекса 1
std::cout << sString << std::endl;
}

1
2
3
4
5
6
7
8
9
10
11

#include <iostream>
#include <string>
 

intmain()

{

std::stringsString(«bbb»);

conststd::stringsInsert(«012345»);

sString.insert(1,sInsert,2,4);// вставляем подстроку sInsert длиной 4, начиная с символа под индексом 2, в строку sString, начиная с индекса 1

std::cout<<sString<<std::endl;

}

Результат:

А вот версия функции insert(), с помощью которой в std::string можно вставить часть строки C-style.

Создание std::string из чисел

Одно заметное упущение в классе std::string — это отсутствие возможности создавать строки из чисел. Например:

#include <iostream>
#include <string>

int main()
{
std::string sFive(5);

return 0;
}

1
2
3
4
5
6
7
8
9

#include <iostream>
#include <string>
 

intmain()

{

std::stringsFive(5);

return;

}

Здесь мы получим ошибку неудачной конвертации значения типа int в std::basic_string. Самый простой способ конвертировать числа в строки — это задействовать класс std::ostringstream, который находится в заголовочном файле sstream. std::ostringstream уже настроен для приема разных входных данных: символов, чисел, строк и т.д. А с помощью std::istringstream можно выполнять обратную конвертацию — выводить строки (либо через оператор вывода , либо через функцию str()).

Например, создадим std::string из разных входных данных:

#include <iostream>
#include <sstream>
#include <string>

template <typename T>
inline std::string ToString(T tX)
{
std::ostringstream oStream;
oStream << tX;
return oStream.str();
}

int main()
{
std::string sFive(ToString(5));
std::string sSevenPointEight(ToString(7.8));
std::string sB(ToString(‘B’));
std::cout << sFive << std::endl;
std::cout << sSevenPointEight << std::endl;
std::cout << sB << std::endl;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

#include <iostream>
#include <sstream>
#include <string>

template<typenameT>

inlinestd::stringToString(TtX)

{

std::ostringstream oStream;

oStream<<tX;

returnoStream.str();

}
 

intmain()

{

std::stringsFive(ToString(5));

std::stringsSevenPointEight(ToString(7.8));

std::stringsB(ToString(‘B’));

std::cout<<sFive<<std::endl;

std::cout<<sSevenPointEight<<std::endl;

std::cout<<sB<<std::endl;

}

Результат:

Обратите внимание, здесь отсутствует проверка на ошибки. Может случиться так, что конвертация в std::string будет неудачной

В таком случае, хорошим вариантом было бы подключить генерацию исключения.

Как разделять строки с использованием регулярных выражений?

Методы регулярного выражения Split () аналогичны методу String.Split (), за исключением того, что метод Regex.Split () разделяет строку на разделителе, определяемом регулярным выражением, вместо набора символов.

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

C#

using System.Text.RegularExpressions;
string str = «test1\n \ntest2\n \ntest3\n \n \ntest4»;
string[] result = Regex.Split(str, «\n\\s*»);
for (int i = 0; i < result.Length; i++)
MessageBox.Show(result);

1
2
3
4
5

usingSystem.Text.RegularExpressions;

stringstr=»test1\n   \ntest2\n   \ntest3\n   \n   \ntest4″;

stringresult=Regex.Split(str,»\n\\s*»);

for(inti=;i<result.Length;i++)

MessageBox.Show(resulti);

Вывод:

C#

test1
test2
test3
test4

1
2
3
4

test1
test2
test3
test4

Мы можем разделить строку на несколько разделителей символов, используя метод String.split().

C#

string input = «test1)(test2)(test3)(test4)(test5»;
string[] result = input.Split(new string[] { «)(» }, StringSplitOptions.None);
foreach (string s in result)
MessageBox.Show(s);

1
2
3
4

stringinput=»test1)(test2)(test3)(test4)(test5″;

stringresult=input.Split(newstring{«)(«},StringSplitOptions.None);

foreach(stringsinresult)

MessageBox.Show(s);

Вывод:

C#

test1
test2
test3
test4
test5

1
2
3
4
5

test1
test2
test3
test4
test5

Конвертация std::string_view в std::string

Объекты класса std::string_view не конвертируются неявным образом в объекты класса std::string, но конвертируются при явном преобразовании:

#include <iostream>
#include <string>
#include <string_view>

void print(std::string s)
{
std::cout << s << ‘\n’;
}

int main()
{
std::string_view sv{ «balloon» };

sv.remove_suffix(3);

// print(sv); // ошибка компиляции: неявная конвертация запрещена

std::string str{ sv }; // явное преобразование

print(str); // ок

print(static_cast<std::string>(sv)); // ок

return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

#include <iostream>
#include <string>
#include <string_view>

voidprint(std::strings)

{

std::cout<<s<<‘\n’;

}

intmain()

{

std::string_viewsv{«balloon»};

sv.remove_suffix(3);

// print(sv); // ошибка компиляции: неявная конвертация запрещена

std::stringstr{sv};// явное преобразование

print(str);// ок

print(static_cast<std::string>(sv));// ок

return;

}

Результат выполнения программы:

Извлечение и пробелы

Важный момент: оператор извлечения работает с «отформатированными» данными, т.е. он игнорирует все пробелы, символы табуляции и символ новой строки. Например:

#include <iostream>

int main()
{
char ch;
while (std::cin >> ch)
std::cout << ch;

return 0;
}

1
2
3
4
5
6
7
8
9
10

#include <iostream>
 

intmain()

{

charch;

while(std::cin>>ch)

std::cout<<ch;

return;

}

Если пользователь введет следующее:

То оператор извлечения пропустит все пробелы и символы новой строки. Следовательно, результат выполнения программы:

Часто пользовательский ввод все же нужен со всеми его пробелами. Для этого класс предоставляет множество функций. Одной из наиболее полезных является фунция get(), которая извлекает символ из входного потока. Вот вышеприведенная программа, но уже с использованием функции get():

#include <iostream>

int main()
{
char ch;
while (std::cin.get(ch))
std::cout << ch;

return 0;
}

1
2
3
4
5
6
7
8
9
10

#include <iostream>
 

intmain()

{

charch;

while(std::cin.get(ch))

std::cout<<ch;

return;

}

Теперь, если мы введем следующее:

То получим:

Функция get() также имеет строковую версию, в которой можно указать максимальное количество символов для извлечения. Например:

#include <iostream>

int main()
{
char strBuf;
std::cin.get(strBuf, 12);
std::cout << strBuf << std::endl;

return 0;
}

1
2
3
4
5
6
7
8
9
10

#include <iostream>
 

intmain()

{

charstrBuf12;

std::cin.get(strBuf,12);

std::cout<<strBuf<<std::endl;

return;

}

Если мы введем следующее:

То получим:

Обратите внимание, программа считывает только первые 11 символов (+ нуль-терминатор). Остальные символы остаются во входном потоке

Один важный нюанс: функция get() не считывает символ новой строки! Например:

#include <iostream>

int main()
{
char strBuf;

// Считываем первые 11 символов
std::cin.get(strBuf, 12);
std::cout << strBuf << std::endl;

// Считываем дополнительно еще 11 символов
std::cin.get(strBuf, 12);
std::cout << strBuf << std::endl;
return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#include <iostream>
 

intmain()

{

charstrBuf12;

// Считываем первые 11 символов

std::cin.get(strBuf,12);

std::cout<<strBuf<<std::endl;

// Считываем дополнительно еще 11 символов

std::cin.get(strBuf,12);

std::cout<<strBuf<<std::endl;

return;

}

Если пользователь введет следующее:

То получит:

И программа сразу же завершит свое выполнение! Почему так? Почему не срабатывает второй ввод данных? Дело в том, что первый get() считывает символы до символа новой строки, а затем останавливается. Второй get() видит, что во входном потоке все еще есть данные и пытается их извлечь. Но первый символ, на который он натыкается — символ новой строки, поэтому происходит второй «Стоп!».

Для решения данной проблемы класс предоставляет функцию getline(), которая работает точно так же, как и функция get(), но при этом может считывать символы новой строки:

#include <iostream>

int main()
{
char strBuf;

// Считываем 11 символов
std::cin.getline(strBuf, 12);
std::cout << strBuf << std::endl;

// Считываем дополнительно еще 11 символов
std::cin.getline(strBuf, 12);
std::cout << strBuf << std::endl;
return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#include <iostream>
 

intmain()

{

charstrBuf12;

// Считываем 11 символов

std::cin.getline(strBuf,12);

std::cout<<strBuf<<std::endl;

// Считываем дополнительно еще 11 символов

std::cin.getline(strBuf,12);

std::cout<<strBuf<<std::endl;

return;

}

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

Если вам нужно узнать количество символов, извлеченных последним getline(), используйте функцию gcount():

#include <iostream>

int main()
{
char strBuf;
std::cin.getline(strBuf, 100);
std::cout << strBuf << std::endl;
std::cout << std::cin.gcount() << » characters were read» << std::endl;

return 0;
}

1
2
3
4
5
6
7
8
9
10
11

#include <iostream>
 

intmain()

{

charstrBuf100;

std::cin.getline(strBuf,100);

std::cout<<strBuf<<std::endl;

std::cout<<std::cin.gcount()<<» characters were read»<<std::endl;

return;

}

Результат:

Функционал std::string

Создание и удаление:

   конструктор — создает или копирует строку;

   деструктор — уничтожает строку.

Размер и ёмкость:

   capacity() — возвращает количество символов, которое строка может хранить без дополнительного перевыделения памяти;

   empty() — возвращает логическое значение, указывающее, является ли строка пустой;

   length(), size() — возвращают количество символов в строке;

   max_size() — возвращает максимальный размер строки, который может быть выделен;

   reserve() — расширяет или уменьшает ёмкость строки.

Доступ к элементам:

   , at() — доступ к элементу по заданному индексу.

Изменение:

   , assign() — присваивают новое значение строке;

   , append(), push_back() — добавляют символы к концу строки;

   insert() — вставляет символы в произвольный индекс строки;

   clear() — удаляет все символы строки;

   erase() — удаляет символы по произвольному индексу строки;

   replace() — заменяет символы произвольных индексов строки другими символами;

   resize() — расширяет или уменьшает строку (удаляет или добавляет символы в конце строки);

   swap() — меняет местами значения двух строк.

Ввод/вывод:

   , getline() — считывают значения из входного потока в строку;

    — записывает значение строки в выходной поток;

   c_str() — конвертирует строку в строку C-style с нуль-терминатором в конце;

   copy() — копирует содержимое строки (которое без нуль-терминатора) в массив типа char;

   data() — возвращает содержимое строки в виде массива типа char, который не заканчивается нуль-терминатором.

Сравнение строк:

   , — сравнивают, являются ли две строки равными/неравными (возвращают значение типа bool);

   , , ,  — сравнивают, являются ли две строки меньше или больше друг друга (возвращают значение типа bool);

   compare() — сравнивает, являются ли две строки равными/неравными (возвращает , или ).

Подстроки и конкатенация:

    — соединяет две строки;

   substr() — возвращает подстроку.

Поиск:

   find — ищет индекс первого символа/подстроки;

   find_first_of — ищет индекс первого символа из набора символов;

   find_first_not_of — ищет индекс первого символа НЕ из набора символов;

   find_last_of — ищет индекс последнего символа из набора символов;

   find_last_not_of — ищет индекс последнего символа НЕ из набора символов;

   rfind — ищет индекс последнего символа/подстроки.

Поддержка итераторов и распределителей (allocators):

   begin(), end() — возвращают «прямой» итератор, указывающий на первый и последний (элемент, который идет за последним) элементы строки;

   get_allocator() — возвращает распределитель;

   rbegin(), rend() — возвращают «обратный» итератор, указывающий на последний (т.е. «обратное» начало) и первый (элемент, который предшествует первому элементу строки — «обратный» конец) элементы строки. Отличие от begin() и end() в том, что движение итераторов происходит в обратную сторону.

Настройка емкости и длины

Хотя StringBuilder является динамическим объектом, который позволяет вам развернуть ряд символов в строке, которые она инкапсулирует, вы можете указать максимальное число содержащихся в ней символов. Это значение называется емкостью объекта, и его не следует путать с длиной строки, которую содержит текущий объект StringBuilder. Например, вы можете создать экземпляр класса StringBuilder со строкой Hello, длина которой составляет 5 символов, указав при этом максимальную емкость объекта 25 символов. При изменении значения StringBuilder размер не перераспределяется, если не достигнута максимальная емкость. Когда это происходит, новое пространство выделяется автоматически, а емкость удваивается. Вы можете указать емкость класса StringBuilder с помощью одного из перегруженных конструкторов. В следующем примере показано, что объект можно развернуть максимум на 25 позиций.

Кроме того, вы можете использовать доступное для чтения или записи свойство Capacity, чтобы задать максимальную длину объекта. В следующем примере используется свойство Capacity для определения максимальной длины объекта.

Метод EnsureCapacity можно использовать для проверки емкости текущего объекта StringBuilder. Если емкость больше переданного значения, изменения не вносятся; однако если емкость меньше переданного значения, текущая емкость изменяется для соответствия переданному значению.

Можно также просмотреть или задать свойство Length. Если вы задали для свойства Length значение больше значения свойства Capacity, значение свойства Capacity будет автоматически изменено на то же самое значение, что и у свойства Length. Если задать для свойства Length значение меньше длины строки в текущем объекте StringBuilder, строка будет укорочена.

Как разделить строку в Си

19 февраля, 2010 by Сергей Тамкович

Категории:ПрограммированиеРазное

Разделение строки на элементы — стандартная задача при обработке текста. Многие высокоуровневые языки предоставляют удобные операторы для решения этой задачи. Например язык Perl позволяет разбить строку используя в качестве разделителя другую строку или регулярное выражение с помощью функции split. Результат разбиения возвращается в виде массива:

@elements = split(/\s/, "very simple example");

В PHP аналогичную роль выполняют функции explode (для деления по текстовому разделителю) и preg_split для деления по регулярному выражению:

$elements1 = explode(" ", "very simple example");
$elements2 = preg_split("/+/", "very simple example");

В Си разделение строки несколько сложнее. Многие программисты, в цикле, ищут разделители с помощью таких функций как index или strstr, а затем меняют его на нулевой байт. Данный подход — громоздкий и неудобный. Гораздо проще воспользоваться функцией strtok. Функция strtok позволяет разбить текстовую строку на токены, используя указанные разделители. Пример использования strtok:

/* strtok usage example */
#include <stdio.h>
#include <string.h>
 
void main () {
    char str = "Very simple example,test";
    char *token, *last;
    printf ("Splitting string \"%s\" into tokens:\n", str);
    token = strtok_r(str, " ,", &last);
    while (token != NULL) {
        printf ("%s\n", token);
        token = strtok_r(NULL, " ,.-", &last);
    }
}

Почему strtok_r, а не strtok и что за третий параметр &last? Функция strtok_r является потоко-безопасной (thread-safe) аналогом функции strtok, третий параметр (**lasts) используется для сохранения текущего положения в оригинальной строке. Поскольку сегодня многопоточные приложения стали нормой, рекомендую использовать именно strtok_r().

char * strtok_r(char *newstring, const char *delimiters, char **save_ptr)

Функция strtok_r работает следующем образом: В случае если переданный указатель newstring отличен от NULL, считается что передана строка (последовательность ненулевых байт завершающаяся нулевым). При первом вызове функции strtok_r, значение сохранённое в save_ptr — игнорируется. Функция strtok_r, находит в строке newstring первый из разделителей, заменяет его на нулевой байт (‘\0’), сохраняет позицию, следующую за нулевым байтом в save_ptr, и возвращает указатель на найденный токен (для первого вызова функции, указатель на найденный токен будет совпадать с указателем на начало строки). Последующие вызовы выглядят следующим образом:

token = strtok_r(NULL, " ,.-", &last);

В случае, если указатель newstring равен NULL, обработка строки начинается с указателя сохранённого в save_ptr, в остальном, алгоритм идентичен первому вызову функции.

Finding Tokens in a String


« И ещё про Ванкувер |
ГЛОНАСС »

Категории:ПрограммированиеРазное

string::string(const string& strString, size_type unIndex) string::string(const string& strString, size_type unIndex, size_type unLength)

   Конструкторы, которые создают новые строки, которые состоят из строки (начиная с индекса ) и количества символов, указанных в .

   Если компилятор встречает , то копирование строки завершается, даже если не был достигнут.

   Если не был указан, то все символы, начиная с , будут использованы.

   Если больше, чем размер строки, то выбрасывается исключение out_of_range.

Например:

#include <iostream>
#include <string>

int main()
{
std::string sSomething(«What a string!»);
std::string sOutput(sSomething, 3);
std::cout << sOutput<< std::endl;
std::string sOutput2(sSomething, 5, 6);
std::cout << sOutput2 << std::endl;

return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13

#include <iostream>
#include <string>
 

intmain()

{

std::stringsSomething(«What a string!»);

std::stringsOutput(sSomething,3);

std::cout<<sOutput<<std::endl;

std::stringsOutput2(sSomething,5,6);

std::cout<<sOutput2<<std::endl;

return;

}

Результат:

Необходимость в строковом классе

В предыдущем уроке мы рассмотрели строки в стиле C, в которых для хранения строки символов используются массивы . Если вы попытаетесь сделать что-нибудь со строками в стиле C, вы очень быстро придете к выводу, что с ними сложно работать, легко испортить и сложно отладить.

Строки в стиле C имеют много недостатков, в первую очередь связанных с тем фактом, что вам придется самостоятельно управлять памятью. Например, если вы захотите присвоить строку «hello!» буферу, вы должны будете сначала динамически выделить память правильной длины для этого буфера:

Не забудьте учесть дополнительный символ для завершающего нуля!

Затем вам нужно будет скопировать в него значение:

Надеюсь, вы сделали буфер достаточно большим, чтобы не было его переполнения!

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

Не забывайте использовать удаление для массива вместо обычного удаления!

Более того, многие интуитивно понятные операторы, которые предоставляет C для работы с числами, такие как присваивание и сравнение, просто не работают со строками в стиле C. Иногда может показаться, что они работают, но на самом деле дают неверные результаты – например, сравнение двух строк в стиле C с использованием на самом деле будет сравнивать указатели, а не строки. Присваивание одной строки в стиле C другой с помощью оператора поначалу будет казаться, что работает, но на самом деле в этом случае выполняется копирование указателя (поверхностное копирование), что обычно не то, что вам нужно. Подобные вещи могут привести к сбоям программы, которые очень трудно найти и отладить!

Суть в том, что работа со строками в стиле C требует запоминания множества особенностей о том, что безопасно/небезопасно, запоминания набора функций с забавными названиями, такими как и , вместо использования интуитивно понятных операторов, и требует много ручного управления памятью.

К счастью, C++ и стандартная библиотека предоставляют гораздо лучший способ работы со строками: классы и . Используя концепции C++, такие как конструкторы, деструкторы и перегрузка операторов, позволяет создавать строки и управлять ими интуитивно и безопасно! Больше никакого управления памятью, никаких странных имен функций и гораздо меньшая вероятность сбоя.

Разделение строк на подстроки в C#

Разделение строк на подстроки в C# также является достаточно частой задачей в программировании. Для этого можно воспользоваться методом

public String[] Split(String[]? separator, int count, StringSplitOptions options);
public String[] Split(String? separator, int count, StringSplitOptions options = StringSplitOptions.None);
public String[] Split(String[]? separator, StringSplitOptions options);
public String[] Split(char[]? separator, int count, StringSplitOptions options);
public String[] Split(String? separator, StringSplitOptions options = StringSplitOptions.None);
public String[] Split(char[]? separator, StringSplitOptions options);
public String[] Split(char separator, StringSplitOptions options = StringSplitOptions.None);
public String[] Split(params char[]? separator);
public String[] Split(char[]? separator, int count);
public String[] Split(char separator, int count, StringSplitOptions options = StringSplitOptions.None);

В качестве параметров метод принимает один или несколько символов (), используемых в качестве разделителя, а на выходе возвращает массив строк.  Рассмотрим работу метода на примере

string s14 = "Эта строка, которая будет разделена на подстроки с использованием двух разделителей";
string[] res = s14.Split(new char[] { ' ', ',' });
foreach (string s in res)
{
    Console.WriteLine(s);
}

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

Эта

строка

которая

будет

разделена

на

подстроки

с

использованием

двух

разделителей

Потоковые классы

Как и istream с ostream, так и потоковые классы для строк предоставляют буфер для хранения данных. Однако в отличие от cin и cout, эти потоковые классы не подключены к каналу ввода/вывода (т.е. к клавиатуре, монитору и т.д.).

Есть 6 потоковых классов, которые используются для чтения и записи строк:

   класс istringstream (является дочерним классу istream);

   класс ostringstream (является дочерним классу ostream);

   класс stringstream (является дочерним классу iostream);

   класс wistringstream;

   класс wostringstream;

   класс wstringstream.

Чтобы использовать класс stringstream, нужно подключить заголовочный файл sstream. Чтобы добавить данные в stringstream, мы можем использовать оператор вставки ():

#include <iostream>
#include <sstream> // для stringstream

int main()
{
std::stringstream myString;
myString << «Lorem ipsum!» << std::endl; // вставляем «Lorem ipsum!» в stringstream
}

1
2
3
4
5
6
7
8

#include <iostream>
#include <sstream> // для stringstream
 

intmain()

{

std::stringstream myString;

myString<<«Lorem ipsum!»<<std::endl;// вставляем «Lorem ipsum!» в stringstream

}

Либо функцию str(string):

#include <iostream>
#include <sstream> // для stringstream

int main()
{
std::stringstream myString;
myString.str(«Lorem ipsum!»); // присваиваем буферу stringstream значение «Lorem ipsum!»
}

1
2
3
4
5
6
7
8

#include <iostream>
#include <sstream> // для stringstream
 

intmain()

{

std::stringstream myString;

myString.str(«Lorem ipsum!»);// присваиваем буферу stringstream значение «Lorem ipsum!»

}

Аналогично, чтобы получить данные обратно из stringstream, мы можем использовать функцию str():

#include <iostream>
#include <sstream> // для stringstream

int main()
{
std::stringstream myString;
myString << «336000 12.14» << std::endl;
std::cout << myString.str();
}

1
2
3
4
5
6
7
8
9

#include <iostream>
#include <sstream> // для stringstream
 

intmain()

{

std::stringstream myString;

myString<<«336000 12.14″<<std::endl;

std::cout<<myString.str();

}

Результат:

Либо оператор извлечения ():

#include <iostream>
#include <sstream> // для stringstream

int main()
{
std::stringstream myString;
myString << «336000 12.14»; // вставляем (числовую) строку в поток

std::string part1;
myString >> part1;

std::string part2;
myString >> part2;

// Выводим числа
std::cout << part1 << » and » << part2 << std::endl;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

#include <iostream>
#include <sstream> // для stringstream
 

intmain()

{

std::stringstream myString;

myString<<«336000 12.14»;// вставляем (числовую) строку в поток

std::stringpart1;

myString>>part1;

std::stringpart2;

myString>>part2;

// Выводим числа

std::cout<<part1<<» and «<<part2<<std::endl;

}

Результат:

Обратите внимание, оператор извлечения () перебирает буфер, автоматически разбивая его на отдельные значения с помощью имеющихся пробелов (т.е. одно использование оператора извлечения () равно одному значению из буфера)

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

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: