Струны 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_view
s в функции, передайте их по значению. Для литералов 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.