//
strcpy(largeStr, ca1); //
strcat(largeStr, " "); //
strcat(largeStr, ca2); //
Проблема в том, что можно легко ошибиться в расчете необходимого размера largeStr
. Кроме того, при каждом изменении значения, которые следует сохранить в largeStr
, необходимо перепроверить правильность вычисления его размера. К сожалению, код, подобный этому, широко распространен в программах. Такие программы подвержены ошибкам и часто приводят к серьезным проблемам защиты.
string
, а не строки в стиле С.
Упражнение 3.37. Что делает следующая программа?
const char ca[] = {'h', 'e', 'l', 'l', 'o'};
const char *cp = ca;
while (*cp) {
cout << *cp << endl;
++cp;
}
Упражнение 3.38. В этом разделе упоминалось, что не только некорректно, но и бессмысленно пытаться сложить два указателя. Почему сложение двух указателей бессмысленно?
Упражнение 3.39. Напишите программу, сравнивающую две строки. Затем напишите программу, сравнивающую значения двух символьных строк в стиле С.
Упражнение 3.40. Напишите программу, определяющую два символьных массива, инициализированных строковыми литералами. Теперь определите третий символьный массив для содержания результата конкатенации этих двух массивов. Используйте функции strcpy()
и strcat()
для копирования этих двух массивов в третий.
3.5.5. Взаимодействие с устаревшим кодом
Множество программ С++ было написано до появления стандартной библиотеки, поэтому они не используют библиотечные типы string
и vector
. Кроме того, многие программы С++ взаимодействуют с программами, написанными на языке С или других языках, которые не могут использовать библиотеку С++. Следовательно, программам, написанным на современном языке С++, вероятно, придется взаимодействовать с кодом, который использует символьные строки в стиле С и/или массивы. Библиотека С++ предоставляет средства, облегчающие такое взаимодействие.
В разделе 3.2.1 была продемонстрирована возможность инициализации строки класса string
строковым литералом:
string s("Hello World"); //
В общем, символьный массив с нулевым символом в конце можно использовать везде, где используется строковый литерал.
• Символьный массив с нулевым символом в конце можно использовать для инициализации строки класса string
или присвоения ей.
• Символьный массив с нулевым символом в конце можно использовать как один из операндов (но не оба) в операторе суммы класса string
или как правый операнд в составном операторе присвоения (+=
) класса string
.
Однако нет никакого простого способа использовать библиотечную строку там, где требуется строка в стиле С. Например, невозможно инициализировать символьный указатель объектом класса string
. Тем не менее класс string
обладает функцией-членом c_str()
, зачастую позволяющей выполнить желаемое.
char *str = s; //
const char *str = s.c_str(); //
Имя функции c_str()
означает, что она возвращает символьную строку в стиле С. Таким образом, она возвращает указатель на начало символьного массива с нулевым символом в конце, содержащим те же символы, что и строка. Тип указателя const char*
не позволяет изменять содержимое массива.
Допустимость массива, возвращенного функцией c_str()
, не гарантируется. Любое последующее использование указателя s
, способное изменить его значение, может сделать этот массив недопустимым.
c_str()
, то следует создать его копию.
В разделе 3.5.1 упоминалось о том, что нельзя инициализировать встроенный массив другим массивом. Инициализировать массив из вектора также нельзя. Однако можно использовать массив для инициализации вектора. Для этого необходимо определить адрес первого подлежащего копированию элемента и элемента, следующего за последним.
int int_arr[] = {0, 1, 2, 3, 4, 5};
//