Строки в С++
Строка - массив символов, заканчивающийся нуль-символом. Нуль-символ — это символ с кодом, равным 0, что записывается в виде обычной управляющей последовательности '\0'. По положению нуль-символа определяется фактическая длина строки.
Строку инициализируют строковым литералом:
В этом примере под строку выделяется 10 байт, 7 из которых занято под символы строки, а восьмой — под нуль-символ.
Если строка при определении инициализируется, размерность можно опускать (компилятор сам выделит соответствующее количество байт):
Пример.
Знак равенства перед строковым литералом означает инициализацию, а не присваивание.
Операция присваивания одной строки другой не определена (так как строка является массивом) и может выполняться с помощью цикла или функций стандартной библиотеки.
Библиотека предоставляет возможности копирования, сравнения, объединения строк, поиска подстроки, определения длины строки и т. д. , а также содержит специальные функции ввода строк и отдельных символов с клавиатуры и из файла.
Пример. Программа запрашивает пароль до трех раз.
Пример. Скопировать строку src в строку dest.
Алгоритм имеет вид:
Проблема. Длина cтроки определяется с помощью функции strlen, которая вычисляет длину, выполняя поиск нуль-символа. Значит здесь строка просматривается дважды.
Решение проблемы. Использовать проверку на нуль-символ прямо в программе. Увеличение индекса можно заменить инкрементом указателей (для этого память под строку src должна выделяться динамически, а также требуется определить доп. указатель и инициализировать его адресом начала строки dest):
Комментарии.
В цикле - посимвольное присваивание элементов строк с одновременной инкрементацией указателей.
Результат операции присваивания — передаваемое значение, которое, собственно, и проверяется в условии цикла, поэтому можно поставить присваивание на место условия, а проверку на неравенство нулю опустить (при этом завершающий нуль копируется в цикле, и отдельного оператора для его присваивания не требуется).
В результате цикл копирования строки принимает вид:
Строку инициализируют строковым литералом:
char str[10] = "Kafedra"; // выделено 10 элементов с номерами от o до 9 // первые элементы - 'K', 'a', 'f', 'e', 'd','r','a','\0'
Если строка при определении инициализируется, размерность можно опускать (компилятор сам выделит соответствующее количество байт):
char str [ ] = "Кафедра_IBM"; // выделено и заполнено 12 байт
char *str = "Kafedra"Cоздан указатель на строковую константу, изменить которую нельзя (например, оператор str[l]='0' не допускается).
Знак равенства перед строковым литералом означает инициализацию, а не присваивание.
Операция присваивания одной строки другой не определена (так как строка является массивом) и может выполняться с помощью цикла или функций стандартной библиотеки.
Библиотека предоставляет возможности копирования, сравнения, объединения строк, поиска подстроки, определения длины строки и т. д. , а также содержит специальные функции ввода строк и отдельных символов с клавиатуры и из файла.
Пример. Программа запрашивает пароль до трех раз.
#include#include int main(){ char s[80], passw[] = "ibm"; // passw - пароль // Можно описать как *passw = "ibm"; int i, к = 0; for (i = 0; !k && i<З ; ii+){ pr1ntf("\nBвeдите пароль:\n"); gets(s); // функция ввода строки if (strstr(s,passw))k = 1; // функция сравнения строк } if (к) pгintf("\nпapoль принят"); else pгintf("\nпapoль не принят"); return 0; }
Алгоритм имеет вид:
char src[10], dest[10]; for (int i = 0; i<=strlen(src); i++) dest[i] = src[i];
Решение проблемы. Использовать проверку на нуль-символ прямо в программе. Увеличение индекса можно заменить инкрементом указателей (для этого память под строку src должна выделяться динамически, а также требуется определить доп. указатель и инициализировать его адресом начала строки dest):
#includeint main(){ char *src = new char [10]; char *dest = new char [10], *d = dest; cin >> src; while ( *src !== 0) *d++ = *src++; *d = 0; // завершающий нуль cout << dest; return 0; }
В цикле - посимвольное присваивание элементов строк с одновременной инкрементацией указателей.
Результат операции присваивания — передаваемое значение, которое, собственно, и проверяется в условии цикла, поэтому можно поставить присваивание на место условия, а проверку на неравенство нулю опустить (при этом завершающий нуль копируется в цикле, и отдельного оператора для его присваивания не требуется).
В результате цикл копирования строки принимает вид:
while ( *d++ = *src++);Замечание. Оба способа работы со строками (через массивы или указатели) работают, но в общем случае лучше пользоваться функциями библиотеки или определенным в стандартной библиотеке C++ классом string, который обеспечивает индексацию, присваивание, сравнение, добавление, объединение строк и поиск подстрок.