C++
станд :: строка
Поиск…
Вступление
Строки - это объекты, которые представляют последовательности символов. Стандартный класс string
обеспечивает простую, безопасную и универсальную альтернативу использованию явных массивов char
при работе с текстом и другими последовательностями символов. string
класс C ++ является частью пространства имен std
и стандартизован в 1998 году.
Синтаксис
// Пустое объявление строки
std :: string s;
// Построение из const char * (c-string)
std :: string s ("Hello");
std :: string s = "Hello";
// Построение с использованием конструктора копирования
std :: string s1 ("Hello");
std :: string s2 (s1);
// Построение из подстроки
std :: string s1 ("Hello");
std :: string s2 (s1, 0, 4); // Копировать 4 символа из позиции 0 из s1 в s2
// Построение из буфера символов
std :: string s1 («Hello World»);
std :: string s2 (s1, 5); // Скопируем первые 5 символов s1 в s2// Создаем конструктор заполнения (только char)
std :: string s (5, 'a'); // s содержит aaaaa
// Конструкция с использованием конструктора диапазонов и итератора
std :: string s1 («Hello World»);
std :: string s2 (s1.begin (), s1.begin () + 5); // Скопируем первые 5 символов s1 в s2
замечания
Прежде чем использовать std::string
, вы должны включить string
заголовка, так как она включает в себя функции / операторы / перегрузки, которые не включают другие заголовки (например, iostream
).
Использование конструктора const char * с nullptr приводит к неопределенному поведению.
std::string oops(nullptr);
std::cout << oops << "\n";
Метод at
std::out_of_range
если index >= size()
.
Поведение operator[]
немного сложнее, во всех случаях оно имеет неопределенное поведение, если index > size()
, но когда index == size()
:
- В строке non-const поведение не определено ;
- В строке
CharT()
ссылка на символ со значениемCharT()
( нулевой символ).
-
CharT()
ссылка на символ со значениемCharT()
( нулевой символ). - Изменение этой ссылки - неопределенное поведение .
Начиная с C ++ 14 вместо использования "foo"
рекомендуется использовать "foo"s
, так как s
- это определяемый пользователем буквенный суффикс , который преобразует const char*
"foo"
в std::string
"foo"
,
Примечание: Вы должны использовать пространство имен std::string_literals
или std::literals
, чтобы получить буквенные s
.
расщепляющий
Используйте std::string::substr
чтобы разделить строку. Существует два варианта этой функции-члена.
Первый принимает начальную позицию, из которой должна начинаться возвращаемая подстрока. Начальная позиция должна быть действительной в диапазоне (0, str.length()]
:
std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(11); // "bar and world!"
Второй занимает начальную позицию и общую длину новой подстроки. Независимо от длины , подстрока никогда не пройдет мимо конца строки источника:
std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(15, 3); // "and"
Обратите внимание, что вы также можете вызывать substr
без аргументов, в этом случае возвращается точная копия строки
std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(); // "Hello foo, bar and world!"
Сменная замена
Заменить по положению
Чтобы заменить часть std::string
вы можете использовать метод replace
из std::string
.
replace
есть много полезных перегрузок:
//Define string
std::string str = "Hello foo, bar and world!";
std::string alternate = "Hello foobar";
//1)
str.replace(6, 3, "bar"); //"Hello bar, bar and world!"
//2)
str.replace(str.begin() + 6, str.end(), "nobody!"); //"Hello nobody!"
//3)
str.replace(19, 5, alternate, 6, 6); //"Hello foo, bar and foobar!"
//4)
str.replace(19, 5, alternate, 6); //"Hello foo, bar and foobar!"
//5)
str.replace(str.begin(), str.begin() + 5, str.begin() + 6, str.begin() + 9);
//"foo foo, bar and world!"
//6)
str.replace(0, 5, 3, 'z'); //"zzz foo, bar and world!"
//7)
str.replace(str.begin() + 6, str.begin() + 9, 3, 'x'); //"Hello xxx, bar and world!"
//8)
str.replace(str.begin(), str.begin() + 5, { 'x', 'y', 'z' }); //"xyz foo, bar and world!"
Заменить вхождения строки другой строкой
Заменить только первое вхождение replace
с with
в str
:
std::string replaceString(std::string str,
const std::string& replace,
const std::string& with){
std::size_t pos = str.find(replace);
if (pos != std::string::npos)
str.replace(pos, replace.length(), with);
return str;
}
Заменить все случаи replace
с with
на str
:
std::string replaceStringAll(std::string str,
const std::string& replace,
const std::string& with) {
if(!replace.empty()) {
std::size_t pos = 0;
while ((pos = str.find(replace, pos)) != std::string::npos) {
str.replace(pos, replace.length(), with);
pos += with.length();
}
}
return str;
}
конкатенация
Вы можете объединить std::string
s с помощью перегруженных операторов +
и +=
. Использование оператора +
:
std::string hello = "Hello";
std::string world = "world";
std::string helloworld = hello + world; // "Helloworld"
Используя оператор +=
:
std::string hello = "Hello";
std::string world = "world";
hello += world; // "Helloworld"
Вы также можете добавить строки C, включая строковые литералы:
std::string hello = "Hello";
std::string world = "world";
const char *comma = ", ";
std::string newhelloworld = hello + comma + world + "!"; // "Hello, world!"
Вы также можете использовать push_back()
для возврата отдельных char
:
std::string s = "a, b, ";
s.push_back('c'); // "a, b, c"
Существует также append()
, что в значительной степени напоминает +=
:
std::string app = "test and ";
app.append("test"); // "test and test"
Доступ к персонажу
Существует несколько способов извлечения символов из std::string
и каждый из них отличается от других.
std::string str("Hello world!");
Оператор [] (п)
Возвращает ссылку на символ с индексом n.
std::string::operator[]
не проверяется границами и не генерирует исключение. Вызывающий отвечает за утверждение, что индекс находится в пределах строки:
char c = str[6]; // 'w'
в (п)
Возвращает ссылку на символ с индексом n.
std::string::at
is bounds checked и будет std::out_of_range
если индекс не находится в пределах строки:
char c = str.at(7); // 'o'
Примечание. Оба эти примера приведут к неопределенному поведению, если строка пуста.
фронт()
Возвращает ссылку на первый символ:
char c = str.front(); // 'H'
назад ()
Возвращает ссылку на последний символ:
char c = str.back(); // '!'
токенизировать
Перечислены от наименее дорогостоящих до самых дорогих во время выполнения:
str::strtok
- самый дешевый стандарт, предоставляемый метод токенизации, он также позволяет изменять разделитель между токенами, но он несет 3 трудности с современным C ++:-
std::strtok
нельзя использовать одновременно для несколькихstrings
(хотя некоторые реализации расширяются для поддержки этого, например:strtok_s
) - По той же причине
std::strtok
не может использоваться одновременно для нескольких потоков (это может быть определено как реализация, например: реализация Visual Studio является потокобезопасной ) - Вызов
std::strtok
изменяетstd::string
он работает, поэтому он не может использоваться дляconst string
s,const char*
s или literal string, чтобы токенизировать любой из них с помощьюstd::strtok
или работать сstd::string
, содержимое которого необходимо сохранить, нужно будет скопировать его, затем копировать можно
Как правило, любая из этих опционных затрат будет скрыта в стоимости распределения токенов, но если требуется самый дешевый алгоритм, и трудности
std::strtok
не могут быть преодолены, рассмотрите решение с ручным сжатием.-
// String to tokenize
std::string str{ "The quick brown fox" };
// Vector to store tokens
vector<std::string> tokens;
for (auto i = strtok(&str[0], " "); i != NULL; i = strtok(NULL, " "))
tokens.push_back(i);
-
std::istream_iterator
использует оператор извлечения потока итеративно. Если входнаяstd::string
ограничена пробелом, то она может расширяться по опцииstd::strtok
, устраняя ее трудности, позволяя встроенную токенизацию, тем самым поддерживая генерациюconst vector<string>
и добавляя поддержку нескольких Обозначение белого пробела:
// String to tokenize
const std::string str("The quick \tbrown \nfox");
std::istringstream is(str);
// Vector to store tokens
const std::vector<std::string> tokens = std::vector<std::string>(
std::istream_iterator<std::string>(is),
std::istream_iterator<std::string>());
-
std::regex_token_iterator
используетstd::regex
для итеративного tokenize. Он обеспечивает более гибкое определение разделителя. Например, не разделенные запятыми и пробелы:
// String to tokenize
const std::string str{ "The ,qu\\,ick ,\tbrown, fox" };
const std::regex re{ "\\s*((?:[^\\\\,]|\\\\.)*?)\\s*(?:,|$)" };
// Vector to store tokens
const std::vector<std::string> tokens{
std::sregex_token_iterator(str.begin(), str.end(), re, 1),
std::sregex_token_iterator()
};
Для regex_token_iterator
дополнительной информации см. Пример regex_token_iterator
.
Преобразование в (const) char *
Чтобы получить const char*
доступ к данным std::string
вы можете использовать функцию члена c_str()
. Имейте в виду, что указатель действителен только до тех пор, пока объект std::string
находится в пределах области действия и остается неизменным, это означает, что на объект могут быть вызваны только методы const
.
Функция члена data()
может использоваться для получения модифицируемого char*
, который может использоваться для управления данными объекта std::string
.
Модифицируемый char*
также можно получить, взяв адрес первого символа: &s[0]
. Внутри C ++ 11 гарантируется, что это приведет к созданию корректной строки с нулевым завершением. Заметим, что &s[0]
корректно сформирован, даже если s
пуст, а &s.front()
не определено, если s
пусто.
std::string str("This is a string.");
const char* cstr = str.c_str(); // cstr points to: "This is a string.\0"
const char* data = str.data(); // data points to: "This is a string.\0"
std::string str("This is a string.");
// Copy the contents of str to untie lifetime from the std::string object
std::unique_ptr<char []> cstr = std::make_unique<char[]>(str.size() + 1);
// Alternative to the line above (no exception safety):
// char* cstr_unsafe = new char[str.size() + 1];
std::copy(str.data(), str.data() + str.size(), cstr);
cstr[str.size()] = '\0'; // A null-terminator needs to be added
// delete[] cstr_unsafe;
std::cout << cstr.get();
Поиск символа (ов) в строке
Чтобы найти символ или другую строку, вы можете использовать std::string::find
. Он возвращает позицию первого символа первого совпадения. Если совпадений не найдено, функция возвращает std::string::npos
std::string str = "Curiosity killed the cat";
auto it = str.find("cat");
if (it != std::string::npos)
std::cout << "Found at position: " << it << '\n';
else
std::cout << "Not found!\n";
Найдено в позиции: 21
Возможности поиска дополнительно расширяются следующими функциями:
find_first_of // Find first occurrence of characters
find_first_not_of // Find first absence of characters
find_last_of // Find last occurrence of characters
find_last_not_of // Find last absence of characters
Эти функции позволяют вам искать символы с конца строки, а также находить отрицательный случай (т. Е. Символы, которые не находятся в строке). Вот пример:
std::string str = "dog dog cat cat";
std::cout << "Found at position: " << str.find_last_of("gzx") << '\n';
Найдено в позиции: 6
Примечание. Помните, что вышеупомянутые функции не выполняют поиск подстрок, а скорее для символов, содержащихся в строке поиска. В этом случае последнее вхождение 'g'
было найдено в позиции 6
(другие символы не были найдены).
Обрезка символов при запуске / окончании
Этот пример требует заголовков <algorithm>
, <locale>
и <utility>
.
Чтобы обрезать последовательность или строку, необходимо удалить все ведущие и конечные элементы (или символы), соответствующие определенному предикату. Сначала мы обрезаем конечные элементы, потому что они не связаны с перемещением каких-либо элементов, а затем обрезают ведущие элементы. Обратите внимание, что приведенные ниже обобщения работают для всех типов std::basic_string
(например, std::string
и std::wstring
), а также для контейнеров последовательностей (например, std::vector
и std::list
).
template <typename Sequence, // any basic_string, vector, list etc.
typename Pred> // a predicate on the element (character) type
Sequence& trim(Sequence& seq, Pred pred) {
return trim_start(trim_end(seq, pred), pred);
}
Обрезка конечных элементов включает поиск последнего элемента, не соответствующего предикату, и стирание оттуда:
template <typename Sequence, typename Pred>
Sequence& trim_end(Sequence& seq, Pred pred) {
auto last = std::find_if_not(seq.rbegin(),
seq.rend(),
pred);
seq.erase(last.base(), seq.end());
return seq;
}
Обрезка ведущих элементов включает в себя поиск первого элемента, не соответствующего предикату, и стирание до него:
template <typename Sequence, typename Pred>
Sequence& trim_start(Sequence& seq, Pred pred) {
auto first = std::find_if_not(seq.begin(),
seq.end(),
pred);
seq.erase(seq.begin(), first);
return seq;
}
Чтобы специализировать выше для обрезки пробелов в std::string
мы можем использовать функцию std::isspace()
как предикат:
std::string& trim(std::string& str, const std::locale& loc = std::locale()) {
return trim(str, [&loc](const char c){ return std::isspace(c, loc); });
}
std::string& trim_start(std::string& str, const std::locale& loc = std::locale()) {
return trim_start(str, [&loc](const char c){ return std::isspace(c, loc); });
}
std::string& trim_end(std::string& str, const std::locale& loc = std::locale()) {
return trim_end(str, [&loc](const char c){ return std::isspace(c, loc); });
}
Аналогично, мы можем использовать функцию std::iswspace()
для std::wstring
и т. Д.
Если вы хотите создать новую последовательность, которая является обрезанной копией, вы можете использовать отдельную функцию:
template <typename Sequence, typename Pred>
Sequence trim_copy(Sequence seq, Pred pred) { // NOTE: passing seq by value
trim(seq, pred);
return seq;
}
Лексикографическое сравнение
Две std::string
s можно сравнить лексикографически с помощью операторов ==
!=
, <
, <=
, >
И >=
:
std::string str1 = "Foo";
std::string str2 = "Bar";
assert(!(str1 < str2));
assert(str > str2);
assert(!(str1 <= str2));
assert(str1 >= str2);
assert(!(str1 == str2));
assert(str1 != str2);
Все эти функции используют метод std::string::compare()
для выполнения сравнения и возвращают для удобства логические значения. Работа этих функций может быть интерпретирована следующим образом, независимо от фактической реализации:
оператор
==
:Если
str1.length() == str2.length()
и каждая пара символов совпадают, то возвращаетtrue
, иначе возвращаетfalse
.оператор
!=
:Если
str1.length() != str2.length()
или одна пара символов не соответствует, возвращаетtrue
, в противном случае возвращаетfalse
.оператор
<
или оператор>
:Находит первую пару символов, сравнивает их, а затем возвращает логический результат.
оператор
<=
или оператор>=
:Находит первую пару символов, сравнивает их, а затем возвращает логический результат.
Примечание . Пара символьная пара означает соответствующие символы в обеих строках одинаковых позиций. Для лучшего понимания, если две строки примера - str1
и str2
, а их длины - n
и m
соответственно, тогда пары символов обеих строк означают каждую пару str1[i]
и str2[i]
где i = 0, 1, 2 str2[i]
.., max (n, m) . Если для любого i, где соответствующий символ не существует, т. Е. Когда i больше или равно n
или m
, он будет считаться самым низким значением.
Ниже приведен пример использования <
:
std::string str1 = "Barr";
std::string str2 = "Bar";
assert(str2 < str1);
Эти шаги заключаются в следующем:
- Сравните первые символы,
'B' == 'B'
- двигаться дальше. - Сравните второй символ,
'a' == 'a'
- двигаться дальше. - Сравните третьи символы,
'r' == 'r'
- перейдите. - Диапазон
str2
теперь исчерпан, а вstr1
все еще есть символы. Таким образом,str2 < str1
.
Преобразование в std :: wstring
В C ++ последовательности символов представлены специализированием std::basic_string
с нативным типом символов. Две основные коллекции, определенные стандартной библиотекой, - std::string
и std::wstring
:
std::string
построена с элементами типаchar
std::wstring
построена с элементами типаwchar_t
Чтобы преобразовать между двумя типами, используйте wstring_convert
:
#include <string>
#include <codecvt>
#include <locale>
std::string input_str = "this is a -string-, which is a sequence based on the -char- type.";
std::wstring input_wstr = L"this is a -wide- string, which is based on the -wchar_t- type.";
// conversion
std::wstring str_turned_to_wstr = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(input_str);
std::string wstr_turned_to_str = std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(input_wstr);
Чтобы улучшить удобство использования и / или читаемость, вы можете определить функции для выполнения преобразования:
#include <string>
#include <codecvt>
#include <locale>
using convert_t = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_t, wchar_t> strconverter;
std::string to_string(std::wstring wstr)
{
return strconverter.to_bytes(wstr);
}
std::wstring to_wstring(std::string str)
{
return strconverter.from_bytes(str);
}
Использование образца:
std::wstring a_wide_string = to_wstring("Hello World!");
Это, безусловно, более std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes("Hello World!")
чем std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes("Hello World!")
.
Обратите внимание: char
и wchar_t
не подразумевают кодировку и не указывают размер в байтах. Например, wchar_t
обычно реализуется как 2-байтовый тип данных и обычно содержит кодированные данные UTF-16 под Windows (или UCS-2 в версиях до Windows 2000) и как 4-байтовый тип данных, закодированный с использованием UTF-32 в Linux. Это контрастирует с более новыми типами char16_t
и char32_t
, которые были введены в C ++ 11 и гарантированно будут достаточно большими, чтобы содержать любой символ UTF16 или UTF32 (или, точнее, кодовую точку ) соответственно.
Использование класса std :: string_view
В C ++ 17 представлен std::string_view
, который является просто не принадлежащим ему диапазоном const char
s, реализуемым как пара указателей или указатель и длина. Это отличный тип параметров для функций, которые требуют немодифицируемых строковых данных. До C ++ 17 для этого было три варианта:
void foo(std::string const& s); // pre-C++17, single argument, could incur
// allocation if caller's data was not in a string
// (e.g. string literal or vector<char> )
void foo(const char* s, size_t len); // pre-C++17, two arguments, have to pass them
// both everywhere
void foo(const char* s); // pre-C++17, single argument, but need to call
// strlen()
template <class StringT>
void foo(StringT const& s); // pre-C++17, caller can pass arbitrary char data
// provider, but now foo() has to live in a header
Все это можно заменить на:
void foo(std::string_view s); // post-C++17, single argument, tighter coupling
// zero copies regardless of how caller is storing
// the data
Обратите внимание, что std::string_view
не может изменять свои базовые данные .
string_view
полезен, когда вы хотите избежать ненужных копий.
Он предлагает полезное подмножество функций, которые выполняет std::string
, хотя некоторые из функций ведут себя по-разному:
std::string str = "lllloooonnnngggg sssstttrrriiinnnggg"; //A really long string
//Bad way - 'string::substr' returns a new string (expensive if the string is long)
std::cout << str.substr(15, 10) << '\n';
//Good way - No copies are created!
std::string_view view = str;
// string_view::substr returns a new string_view
std::cout << view.substr(15, 10) << '\n';
Пересечение каждого символа
std::string
поддерживает итераторы, поэтому вы можете использовать цикл, основанный на диапазоне, для повторения каждого символа:
std::string str = "Hello World!";
for (auto c : str)
std::cout << c;
Вы можете использовать «традиционные» for
цикла в цикле через каждый символ:
std::string str = "Hello World!";
for (std::size_t i = 0; i < str.length(); ++i)
std::cout << str[i];
Преобразование в целые числа / типы с плавающей запятой
std::string
содержащая число, может быть преобразована в целочисленный тип или тип с плавающей точкой, используя функции преобразования.
Обратите внимание: все эти функции перестают анализировать входную строку, как только они сталкиваются с нечисловым символом, поэтому "123abc"
будет преобразован в 123
.
Семейство функций std::ato*
преобразует строки C-стиля (массивы символов) в типы с целыми или с плавающей запятой:
std::string ten = "10";
double num1 = std::atof(ten.c_str());
int num2 = std::atoi(ten.c_str());
long num3 = std::atol(ten.c_str());
long long num4 = std::atoll(ten.c_str());
Однако использование этих функций не рекомендуется, потому что они возвращают 0
если они не могут проанализировать строку. Это плохо, потому что 0
также может быть допустимым результатом, если, например, входная строка была «0», поэтому невозможно определить, действительно ли было выполнено преобразование.
Новое семейство функций std::sto*
преобразует std::string
s в типы с целыми числами или с плавающей точкой и генерирует исключения, если они не могут проанализировать их ввод. Вы должны использовать эти функции, если это возможно :
std::string ten = "10";
int num1 = std::stoi(ten);
long num2 = std::stol(ten);
long long num3 = std::stoll(ten);
float num4 = std::stof(ten);
double num5 = std::stod(ten);
long double num6 = std::stold(ten);
Кроме того, эти функции также обрабатывают восьмеричные и шестнадцатеричные строки, в отличие от семейства std::ato*
. Второй параметр - это указатель на первый неотвернутый символ во входной строке (здесь не проиллюстрирован), а третий параметр - база для использования. 0
- автоматическое обнаружение восьмеричного (начиная с 0
) и шестнадцатеричного (начиная с 0x
или 0X
), и любое другое значение является базой для использования
std::string ten = "10";
std::string ten_octal = "12";
std::string ten_hex = "0xA";
int num1 = std::stoi(ten, 0, 2); // Returns 2
int num2 = std::stoi(ten_octal, 0, 8); // Returns 10
long num3 = std::stol(ten_hex, 0, 16); // Returns 10
long num4 = std::stol(ten_hex); // Returns 0
long num5 = std::stol(ten_hex, 0, 0); // Returns 10 as it detects the leading 0x
Преобразование между кодировками символов
Преобразование между кодировками легко с C ++ 11, и большинство компиляторов могут справиться с ним кросс-платформенным способом с помощью <codecvt>
и <locale>
.
#include <iostream>
#include <codecvt>
#include <locale>
#include <string>
using namespace std;
int main() {
// converts between wstring and utf8 string
wstring_convert<codecvt_utf8_utf16<wchar_t>> wchar_to_utf8;
// converts between u16string and utf8 string
wstring_convert<codecvt_utf8_utf16<char16_t>, char16_t> utf16_to_utf8;
wstring wstr = L"foobar";
string utf8str = wchar_to_utf8.to_bytes(wstr);
wstring wstr2 = wchar_to_utf8.from_bytes(utf8str);
wcout << wstr << endl;
cout << utf8str << endl;
wcout << wstr2 << endl;
u16string u16str = u"foobar";
string utf8str2 = utf16_to_utf8.to_bytes(u16str);
u16string u16str2 = utf16_to_utf8.from_bytes(utf8str2);
return 0;
}
Имейте в виду, что Visual Studio 2015 обеспечивает поддержку для этих преобразований, но ошибка в их реализации библиотеки требует использования другого шаблона для wstring_convert
при работе с char16_t
:
using utf16_char = unsigned short;
wstring_convert<codecvt_utf8_utf16<utf16_char>, utf16_char> conv_utf8_utf16;
void strings::utf16_to_utf8(const std::u16string& utf16, std::string& utf8)
{
std::basic_string<utf16_char> tmp;
tmp.resize(utf16.length());
std::copy(utf16.begin(), utf16.end(), tmp.begin());
utf8 = conv_utf8_utf16.to_bytes(tmp);
}
void strings::utf8_to_utf16(const std::string& utf8, std::u16string& utf16)
{
std::basic_string<utf16_char> tmp = conv_utf8_utf16.from_bytes(utf8);
utf16.clear();
utf16.resize(tmp.length());
std::copy(tmp.begin(), tmp.end(), utf16.begin());
}
Проверка, является ли строка префиксом другого
В C ++ 14 это легко сделать с помощью std::mismatch
которая возвращает первую несоответствующую пару из двух диапазонов:
std::string prefix = "foo";
std::string string = "foobar";
bool isPrefix = std::mismatch(prefix.begin(), prefix.end(),
string.begin(), string.end()).first == prefix.end();
Следует отметить , что диапазон-и с половиной версия mismatch()
существовала до С ++ 14, но это небезопасно в случае, когда вторая строка является короче из двух.
Мы все еще можем использовать версию std::mismatch()
в диапазоне от половины до половины, но нам нужно сначала проверить, что первая строка не превосходит вторую:
bool isPrefix = prefix.size() <= string.size() &&
std::mismatch(prefix.begin(), prefix.end(),
string.begin(), string.end()).first == prefix.end();
С std::string_view
мы можем написать прямое сравнение, которое мы хотим, не беспокоясь о накладных std::string_view
или создании копий:
bool isPrefix(std::string_view prefix, std::string_view full)
{
return prefix == full.substr(0, prefix.size());
}
Преобразование в std :: string
std::ostringstream
можно использовать для преобразования любого потокового типа в строковое представление, вставив объект в объект std::ostringstream
(с оператором вставки потока <<
) и затем преобразуя весь std::ostringstream
в std::string
.
Например, для int
:
#include <sstream>
int main()
{
int val = 4;
std::ostringstream str;
str << val;
std::string converted = str.str();
return 0;
}
Написав свою собственную функцию преобразования, просто:
template<class T>
std::string toString(const T& x)
{
std::ostringstream ss;
ss << x;
return ss.str();
}
работает, но не подходит для критического кода производительности.
Определяемые пользователем классы могут при необходимости реализовать оператор вставки потока:
std::ostream operator<<( std::ostream& out, const A& a )
{
// write a string representation of a to out
return out;
}
Помимо потоков, начиная с C ++ 11, вы также можете использовать std::to_string
(и std::to_wstring
), которая перегружена для всех основных типов и возвращает строковое представление ее параметра.
std::string s = to_string(0x12f3); // after this the string s contains "4851"