Поиск…


Вступление

Строки - это объекты, которые представляют последовательности символов. Стандартный класс 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() :

C ++ 11
  1. В строке non-const поведение не определено ;
  2. В строке CharT() ссылка на символ со значением CharT() ( нулевой символ).
C ++ 11
  1. CharT() ссылка на символ со значением CharT() ( нулевой символ).
  2. Изменение этой ссылки - неопределенное поведение .

Начиная с 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!"
C ++ 14
//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!"
C ++ 11
//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'
C ++ 11

Примечание. Оба эти примера приведут к неопределенному поведению, если строка пуста.


фронт()

Возвращает ссылку на первый символ:

char c = str.front(); // 'H'

назад ()

Возвращает ссылку на последний символ:

char c = str.back(); // '!'

токенизировать

Перечислены от наименее дорогостоящих до самых дорогих во время выполнения:

  1. 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);

Живой пример

  1. 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>());

Живой пример

  1. std::regex_token_iterator использует std::regex для итеративного tokenize. Он обеспечивает более гибкое определение разделителя. Например, не разделенные запятыми и пробелы:
C ++ 11
// 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 .

C ++ 17

Функция члена data() может использоваться для получения модифицируемого char* , который может использоваться для управления данными объекта std::string .

C ++ 11

Модифицируемый char* также можно получить, взяв адрес первого символа: &s[0] . Внутри C ++ 11 гарантируется, что это приведет к созданию корректной строки с нулевым завершением. Заметим, что &s[0] корректно сформирован, даже если s пуст, а &s.front() не определено, если s пусто.

C ++ 11
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> .

C ++ 11

Чтобы обрезать последовательность или строку, необходимо удалить все ведущие и конечные элементы (или символы), соответствующие определенному предикату. Сначала мы обрезаем конечные элементы, потому что они не связаны с перемещением каких-либо элементов, а затем обрезают ведущие элементы. Обратите внимание, что приведенные ниже обобщения работают для всех типов 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);

Эти шаги заключаются в следующем:

  1. Сравните первые символы, 'B' == 'B' - двигаться дальше.
  2. Сравните второй символ, 'a' == 'a' - двигаться дальше.
  3. Сравните третьи символы, 'r' == 'r' - перейдите.
  4. Диапазон 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

В 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';

Пересечение каждого символа

C ++ 11

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());
C ++ 11
long long num4 = std::atoll(ten.c_str());

Однако использование этих функций не рекомендуется, потому что они возвращают 0 если они не могут проанализировать строку. Это плохо, потому что 0 также может быть допустимым результатом, если, например, входная строка была «0», поэтому невозможно определить, действительно ли было выполнено преобразование.

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

C ++ 11
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

В 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, но это небезопасно в случае, когда вторая строка является короче из двух.

C ++ 14

Мы все еще можем использовать версию std::mismatch() в диапазоне от половины до половины, но нам нужно сначала проверить, что первая строка не превосходит вторую:

bool isPrefix = prefix.size() <= string.size() &&
    std::mismatch(prefix.begin(), prefix.end(),
        string.begin(), string.end()).first == prefix.end();
C ++ 17

С 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

Помимо потоков, начиная с C ++ 11, вы также можете использовать std::to_stringstd::to_wstring ), которая перегружена для всех основных типов и возвращает строковое представление ее параметра.

std::string s = to_string(0x12f3);  // after this the string s contains "4851"


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow