Струны C-стиля

Строки в стиле C следует избегать, за исключением случаев взаимодействия с библиотеками C. Функции библиотеки строк C не обеспечивают проверку границ и поддержку выделения памяти. Они представлены в виде массива символов. Последний символ строки — нулевой символ \0, поэтому код, использующий строку, знает, где она заканчивается. Пространство, необходимое для строки, всегда на единицу больше, чем количество читаемых символов.

Строковые литералы

Строки, заключенные в кавычки, являются строковыми литералами. Они хранятся в доступной только для чтения части памяти. Поскольку они хранятся в разделах только для чтения, попытка изменить строковые литералы приводит к неопределенному поведению. Пример:

char *str = "world";
str[0] = 'y'; //undefined behavior

Если код соответствует стандарту и присваивает строковому литералу значение const char*, компилятор отлавливает попытки изменить строковые литералы:

const char * str = "world";
str[0] = 'k'; //compiler will flag this as error.

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

char str[] = "hello world";
str[0] = 'y';

Необработанные строковые литералы

C++ предлагает необработанные строковые литералы, представляющие собой литералы, охватывающие несколько строк кода, не требующие экранирования встроенных двойных кавычек и не обрабатывающие escape-последовательности какой-либо специальной логикой. Пример:

const char* str = R"(Brave New World)";
const char* str = R"(Line1: Brave 
Line2: New World)";

Чтобы использовать ) или ( в необработанных строковых литералах, используйте уникальные последовательности разделителей, подобные следующим:

const char* str = R"-(Embedded ) parens)-";

станд::строка

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

string one("hello");
string two("world");
string final;
final = one + " " + two;

Кроме того, ==, !=, < и т. д. перегружены, поэтому они используют настоящие строковые символы. Для совместимости можно вызвать c_str(), чтобы вернуть строку в стиле C, но это должна быть последняя операция, и ее никогда не следует выполнять в стеке, выделенном string. Поскольку строковые литералы выводятся как const char*, можно использовать s для интерпретации строкового литерала как std::string:

auto myStr = "hello brave world"s;

Конверсии

Пространство имен std имеет несколько функций для преобразования чисел в строки. Примеры: string to_string(int vaL) и string to_string(double val). Для преобразования строк в числа используйте такие функции, как int stoi(const string& s, size_t *idx = 0, int base=10). Пример:

const string toConvert = " 123ABC";
size_t index = 0;
int value = stoi(toConvert,&index); //index will be the index of 'A'.

std::string_view

string_view — это string только для чтения, но без накладных расходов const string&. Он не копирует строки. Чтобы объединить string_view со строкой, используйте функцию-член data():

string str = "Hard";
string_view sview = " Rock";
auto result = str + sview.data();

Чтобы передать string_views в функции, передайте их по значению. Для литералов string_view используйте 'sv':

auto sview = "Sample string view"sv;
string_view extractLastDelimitedElement(string_view sv, char delimiter)
{
    return sv.substr(sv.rfind(delimiter));
}

Использованная литература:

Грегуар, М. (2018). Профессиональный C++. Индиана, Индиана: John Wiley & Sons.