<< Предыдущая Оглавление Следующая >>


3.2. Работа со строками

В языке С++ нет специального типа данных для строковых переменных. Для этих целей используются массивы символов (тип char). Следующий пример демонстрирует использование строк в программе:

char str_1[100] = {‘П’,’р’,’и’,’в’,’е’,’т’,’\0’};
char str_2[100] = “Привет”;
char str_3[] = “Привет”;
printf(“%s\n%s\n%s\n”,str_1,str_2,str_3);

В приведенном примере показаны три способа инициализации строковых переменных. Первый способ является классическим объявлением массива, второй и третий используются специально для строк. Причем в последнем случае, компилятор сам определяет нужную длину массива для записи строки. Анализируя первый и второй способы инициализации массива символов возникает вопрос: каким образом язык С++ «знает» где заканчивается строка? Действительно, массив str_2 содержит 100 элементов, а массив str_3 меньше 100, тем не менее длина строки и в первом и во втором случаях одна и та же. Такой эффект достигается за счет использования специальных управляющих кодов, которые говорят где заканчивается строка или где используется перенос внутри одной строки и т.п. В частности символ ‘\0’ означает в языке С++ конец строки и все символы после него игнорируются как символы строки. Следующий пример показывает особенность использования данного специального символа.

char str1[10] = {‘Л’,’е’,’к’,’ц’,’и’,’я’,’\0’};
char str2[10] = {‘Л’,’е’,’к’,’ц’, ’\0’,’и’,’я’ };
char str3[10] = {‘Л’,’е’, ’\0’,’к’,’ц’,’и’,’я’ };
printf(“%s\n%s\n%s\n”,str1,str2,str3);

Результатом работы данного кода будет вывод следующих трех строк:

Лекция
Лекц
Ле

Из этого примера видно как символ конца строки ‘\0’ влияет на длину строк. Таким образом, чтобы подсчитать длину строки (число символов) необходимо считать символы до тех пор, пока не встретится символ ‘\0’ или не будет достигнут конец массива. В листинге 3.1 представлена программа вычисления длины строки.

Листинг 3.1. Программа вычисления длины строки.

#include
int main(void)
{
char str[] = “Привет мир!”;
int size_array = sizeof(str);
int length = 0;
while(length < size_array && str[length] != ‘\0’) length++;
printf(“Длина строки = %d.\n”,length);

return 0;
}

В представленном примере сначала выполняется инициализация строки в массиве str. Затем вычисляется размер массива с помощью функции sizeof(), которая возвращает число байт занимаемое массивом в памяти ЭВМ. Учитывая, что тип char также представляет собой один байт, то данная функция даст размер массива. После этого инициализируется счетчик символов length и выполняется цикл while с очевидными условиями. В результате переменная length будет содержать число символов в строке, либо размер массива. Подобная функция вычисления размера строк уже реализована в стандартной библиотеке языка С++ string.h со следующим синтаксисом:

int strlen(char* str);

где char* str – указатель на строку (об указателях речь пойдет ниже). Следующая программа показывает правило использования функции strlen().

Листинг 3.2. Пример использования функции strlen().

#include
#include
int main(void) {
char str[] = “Привет мир!”;
int length = strlen(str);
printf(“Длина строки = %d.\n”,length);
return 0;
}

Результатом работы программы будет вывод на экран числа 11. Учитывая, что первый символ имеет нулевой индекс, то можно заметить, что данная функция считает и символ ‘\0’.

Теперь рассмотрим правила присваивания одной строковой переменной другой. Допустим объявлены две строки

char str1[] = “Это первая строка”;
char str2[] = “Это вторая строка”;

и необходимо выполнить оператор присваивания

str1 = str2;

При такой записи оператора присваивания компилятор выдаст сообщение об ошибке. Для того чтобы выполнить копирование необходимо перебирать по порядку элементы одного массива и присваивать их другому массиву. Это демонстрируется на следующем примере:

char str1[] = “Это первая строка”;
char str2[] = “Это вторая строка”;
int size_array = sizeof(str1);
int i=0;
while(i < size_array && str1[i] != ‘\0’) {
str2[i] = str1[i];
i++;
}
str2[i] = ‘\0’;

В приведенном фрагменте программы выполняется перебор элементов массива str1 с помощью цикла while и значение i-го элемента записывается в массив str2. Данная операция выполняется до тех пор, пока либо не будет достигнут конец массива, либо не встретится символ конца строки ‘\0’. Затем, после выполнения цикла, в конец массива str2 записывается символ ‘\0’. Таким образом, выполняется копирование одной строки в другую. Подобная функция также реализована в библиотеке языка С++ string.h и имеет следующее определение:

char* strcpy(char* dest, char* src);

Она выполняет копирование строки src в строку dest и возвращает строку dest. В листинге 3.3 показано правило использования функции strcpy().

Листинг 3.3. Пример использования функции strcpy().

#include
#include
int main(void) {
char src[] = “Привет мир!”;
char dest[100];
strcpy(dest,src);
printf(“%s\n”,dest);
return 0;
}

Кроме операций вычисления длины строки и копирования строк важной является операция сравнения двух строк между собой. В языке С++ две строки считаются одинаковыми, если равны их длины и элементы одной строки равны соответствующим элементам другой. Следующий алгоритм выполняет такое сравнение:

char str1[] = “Это первая строка”;
char str2[] = “Это вторая строка”;
int length = strlen(str1);
int length2 = strlen(str2);

if(length != length2) {
printf(“Срока %s не равна строке %s\n”,str1,str2);
return 0;
}

for(int i=0;i < length;i++)
if(str1[i] != str2[i]) {
printf(“Срока %s не равна строке %s\n”,str1,str2);
break;
}
}
if(i == length)
printf(“Срока %s равна строке %s\n”,str1,str2);

Приведенный пример показывает возможность досрочного завершения программы путем использования оператора return. Данный оператор вызывается, если длины строк не совпадают. Также реализуется цикл, в котором сравниваются элементы массивов str1 и str2. Если хотя бы один элемент не будет совпадать, то на экран выведется сообщение «Строка … не равна строке…» и цикл завершится с помощью оператора break. В противном случае (равенства всех элементов) переменная i будет равна переменной length и тогда на экран выводится сообщение о совпадении строк. Подобный алгоритм сравнения двух строк реализован в функции

int strcmp(char* str1, char* str2);

библиотеки . Данная функция возвращает нуль, если строки str1 и str2 равны и не нуль в противном случае. Приведем пример использования данной функции.

char str1[] = “Это первая строка”;
char str2[] = “Это вторая строка”;
if(strcmp(str1,str2) == 0) printf(“Срока %s равна строке %s\n”,str1,str2);
else printf(“Срока %s не равна строке %s\n”,str1,str2);

В языке С++ имеется несколько функций, позволяющих вводить строки с клавиатуры. Самой распространенной из них является ранее рассмотренная функция scanf(), которой в качестве параметра передается ссылка на массив символов:

char str[100];
scanf(“%s”,str);

В результате выполнения этого кода, переменная str будет содержать введенную пользователем последовательность символов. Кроме функции scanf() также часто используют функцию gets() библиотеки stdio.h, которая в качестве аргумента принимает ссылку на массив символов:

gest(str);

Данная функция считывает символы до тех пор, пока пользователь не нажмет клавишу Enter, т.е. введет символ перевода строки ‘\n’. Затем она записывает вместо символа ‘\n’ символ ‘\0’ и передает строку вызывающей программе.

Для вывода строк на экран помимо функции printf() можно использовать также функцию puts() библиотеки stdio.h, которая более проста в использовании. Следующий пример демонстрирует применение данной функции.

#define DEF “Заданная строка”
char str[] = “Это первая строка”;
puts(str);
puts(DEF);
puts(&str[4]);

Результат работы следующий:

Это первая строка
Заданная строка
первая строка

Как видно из полученных результатов, функция puts() автоматически переводит курсор на следующую строку и последующие строки выводятся с новой строки. Кроме того, строки можно задавать с помощью директивы #define и выводить их с помощью функции puts. Также можно менять начало вывода строки путем изменения адреса ее начала.

Еще одной удобной функцией работы со строками является функция sprintf() библиотеки stdio.h. Ее действие аналогично рассмотренной ранее функции printf() с той лишь разницей, что результат вывода заносится в строковую переменную, а не на экран:

int age;
char name[100], str[100];
printf(“Введите Ваше имя: ”);
scanf(“%s”,name);
printf(“Введите Ваш возраст: ”);
scanf(“%d”,&age);
sprintf(str,”Здраствуйте %s. Ваш возраст %d лет”,name,age);
puts(str);

В результате массив str будет содержать строку «Здраствуйте … Ваш возраст…».

Анализ последнего примера показывает, что с помощью функции sprintf() можно преобразовывать числовые переменные в строковые, объединять несколько строк в одну и т.п. Вместе с тем библиотека содержит специальные функции по преобразованию строк в цифры. Дело в том, что строка «100» и цифра 100 в памяти компьютера представляются по-разному. Строка «100» - это последовательность трех символов ‘1’,’0’,’0’, а число 100 – это значение, которое может быть представлено в виде одного байта или храниться в переменной типа int. При программировании часто бывает необходимо выполнять преобразование строк в числа. Это осуществляется с помощью функций atoi(), atol(), atof(). В листинге 3.4 показаны особенности применения данных функций.

Листинг 3.4. Программа преобразования строк в цифры.

#include
#include
int main()
{
char str_i[] = “120”;
char str_l[] = “120000”;
char str_f[] = “120.50”;
int var_i = atoi(str_i);
long var_l = atol(str_l);
float var_f = atof(str_f);

return 0;
}

В результате выполнение данной программы, переменные var_i, var_l и var_f будут содержать значения 120, 120000 и 120.50 соответственно.

Видео по теме

С++ с нуля: урок 1 - переменные, оператор присваивания

С++ с нуля: урок 2 - арифметические операции

С++ с нуля: урок 3 - директивы препроцессора

С++ с нуля, урок 4: условные операторы if и switch

С++ с нуля: урок 5 - операторы циклов while, for и do while

С++ с нуля: урок 6 - массивы, метод всплывающего пузырька

С++ с нуля: урок 7 - строки и функции работы с ними

С++ с нуля: урок 8 - функции: прототипы, перегрузка, рекурсия

С++ с нуля: урок 9 - области видимости переменных

С++ с нуля: урок 10 - битовые операции И, ИЛИ, НЕ, XOR

С++ с нуля: урок 11 - структуры

С++ с нуля: урок 12 - объединения, перечисления, typedef

С++ с нуля: урок 13 - указатели и ссылки, выделение памяти

С++ с нуля: урок 14 (часть 1) - функции работы с файлами

С++ с нуля: урок 14 (часть 2) - функции работы с файлами

С++ с нуля: урок 15 - стек, теория и практика

С++ с нуля: урок 16 - связные списки, теория и практика

С++ с нуля: урок 17 - бинарное дерево, теория и практика



<< Предыдущая Оглавление Следующая >>