- •Лабораторная работа 1
 - •Лабораторная работа 2 Переменные и константы. Базовые типы. Арифметические операции
 - •Операции
 - •Ввод и вывод данных
 - •Лабораторная работа 3 Циклический и ветвящийся поток управления
 - •Алгоритмы разветвляющейся структуры
 - •Операторы выбора
 - •Операторы циклов
 - •Операторы перехода
 - •Задание
 - •Лабораторная работа 4 Функции. Вызов функций с формальными параметрами, передаваемыми по значению
 - •Задание
 - •Лабораторная работа 5 Одномерные массивы
 - •Задание
 - •Лабораторная работа 6 Многомерные массивы
 - •Задание
 - •Лабораторная работа 7 Функции для работы с символами
 - •Лабораторная работа 8 Строки, литералы. Передача строк в функции
 - •Строки и литералы
 - •Библиотечные функции для работы со строками
 - •Выделение памяти под строки
 - •Передача строк в качестве параметров функций
 - •Задание
 - •Лабораторная работа 9 Указатели и динамические массивы
 - •Задание
 - •Варианты
 - •Лабораторная работа 10 Динамические структуры данных
 - •Структуры и указатели
 - •Задание
 - •Лабораторная работа 11 Объектно-ориентированное программирование. Создание классов и объектов
 - •Задание
 - •Лабораторная работа 12 Знакомство со средой быстрой разработки приложений. Использование компонент библиотеки vcl
 - •Лабораторная работа 13 Вывод в форму результатов работы программы
 - •Лабораторная работа 14 Изучение обработчиков событий компонентов библиотеки vcl
 - •Лабораторная работа 15 Использование таймера для создания различных эффектов
 - •Лабораторная работа 16 Рисование в канве. Построение графиков функций
 - •Лабораторная работа 17 Изучение принципа работы текстового редактора
 - •Список рекомендуемой литературы
 - •Оглавление
 
Лабораторная работа 8 Строки, литералы. Передача строк в функции
Цель работы − приобрести навыки работы со строками и литералами в языке С++, получить практические навыки при передаче строк в функции.
Теория
Строки и литералы
Для того чтобы работать с текстом, в языке Си++ не существует особого встроенного типа данных. Текст представляется в виде последовательности знаков (байтов), заканчивающейся нулевым байтом.
Строки представляются в виде массива байтов.
Пример
char string[20];
string[0] = ’H’;
string[1] = ’e’;
string[2] = ’l’;
string[3] = ’l’;
string[4] = ’o’;
string[5] = 0;
В массиве string записана строка «Hello». При этом мы использовали только 6 из 20 элементов массива.
Для записи строковых констант в программе используются литералы. Литерал − это последовательность знаков, заключенная в двойные кавычки.
Пример
«Это строка»
«0123456789»
«*»
Заметим, что символ, заключенный в двойные кавычки, отличается от символа, заключенного в апострофы. Литерал «*» обозначает два байта: первый байт содержит символ звездочки, второй байт содержит ноль. Константа ’*’ обозначает один байт, содержащий знак звездочки.
| 
				 A  | 
				 \0  | 
				 
  | 
				 A  | 
| 
				 ”A” − строка (2 байта)  | 
				 
  | 
				 ’A’ − символ (1 байт)  | |
Рис. 8
С помощью литералов можно инициализировать массивы.
Пример
char alldigits[] = «0123456789»;
Размер массива явно не задан, он определяется исходя из размера инициализирующего его литерала, в данном случае 11 (10 символов плюс нулевой байт).
При работе со строками особенно часто используется связь между массивами и указателями. Значение литерала − это массив неизменяемых байтов нужного размера. Строковый литерал может быть присвоен указателю на char.
Пример
const char* message = «Сообщение программы»;
Значение литерала − это адрес его первого байта, указатель на начало строки. В следующем примере функция CopyString копирует первую строку во вторую.
Пример
void CopyString(char* src, char* dst) {
while (*dst++ = *src++)
*dst = 0; }
int main()
{
char first[] = «Первая строка»;
char second[100];
CopyString(first, second);
return 1;
}
Указатель на байт (тип char*) указывает на начало строки. Предположим, нам нужно подсчитать количество цифр в строке, на которую показывает указатель str.
Пример
#include
int k=0;
while (*str!= 0) //признак конца строки − ноль
{
if (isdigit(*str++)) //проверить байт, на который указывает
//str, и сдвинуть указатель на следующий
//байт
k++;
}
При выходе из цикла while переменная count содержит количество цифр в строке str, а сам указатель str указывает на конец строки − нулевой байт. Чтобы проверить, является ли текущий символ цифрой, используется функция isdigit. Это одна из многих стандартных функций языка, предназначенных для работы с символами и строками.
Библиотечные функции для работы со строками
С помощью функций стандартной библиотеки языка, которые содержатся в заголовочном файле string.h, реализованы многие часто используемые операции над символьными строками. В большинстве своем в качестве строк они воспринимают указатели. Прежде чем использовать эти указатели в программе, нужно подключить их описания с помощью оператора #include.
Здесь мы будем иметь дело с двумя группами функций. Функции с именами, начинающимися с str, работают с С-строками, в которых нулевой байт означает конец строки. Функции же, начинающиеся с mem, работают с массивами символов, следовательно, позволяют работать и с нулевыми байтами.
Обратите внимание – функции вроде копирования и слияния строк (модифицирующие один из аргументов) изменяют первый аргумент, а не второй. Приведем ряд наиболее употребительных функций для работы со строками (таблица).
| 
			 Прототип функции  | 
			 Краткое описание  | 
			 Примечание  | 
| 
			 unsigned strlen(const char* s);  | 
			 Вычисляет длину строки s  | 
			 
  | 
| 
			 int strcmp(const char* s1, const char* s2);  | 
			 Сравнивает строки s1 и s2  | 
			 Если s1<s2, то результат отрицательный, если s1==s2, то результат равен 0, если s2>s1 – результат положительный  | 
| 
			 int strcnmp(const char* s1, const char* s2);  | 
			 Сравнивает первые n символов строк s1 и s2  | 
			 Если s1<s2, то результат отрицательный, если s1==s2, то результат равен 0, если s2>s1 – результат положительный  | 
| 
			 char* strcpy(char* s1, const char* s2);  | 
			 Копирует символы строки s1 в строку s2  | 
			 
  | 
| 
			 char* strncpy(char* s1, const char* s2, int n);  | 
			 Копирует n символов строки s1 в строку s2  | 
			 Конец строки отбрасывается или дополняется пробелами  | 
| 
			 char* strcat(char* s1, const char* s2);  | 
			 Приписывает строку s2 к строке s1  | 
			 
  | 
| 
			 char* strncat(char* s1, const char* s2);  | 
			 Приписывает первые n символов строки s2 к строке s1  | 
			 
  | 
| 
			 char* strdup(const char* s);  | 
			 Выделяет память и переносит в нее копию строки s  | 
			 При выделении памяти используются функции  | 
| 
			 char *strchr(char *s, int c)  | 
			 Возвращает указатель на первый встреченный в строке символ c. Если такого символа в строке не оказалось, возвращает NULL  | 
			 
  | 
Продолжение табл.
| 
			 Прототип функции  | 
			 Краткое описание  | 
			 Примечание  | 
| 
			 void *memcpy(void *dst, void *src, size_t len)  | 
			 Копирует len байтов (включая нулевые) из src в dst. Возвращает dst  | 
			 
  | 
| 
			 void *memove(void *dst, void *src, size_t len)  | 
			 Делает то же, что и memcpy  | 
			 Это – единственная функция, которая по стандарту обязана правильно копировать перекрывающиеся объекты  | 
| 
			 int memcmp(void *s1, void *s2, size_t len)  | 
			 Аналог strcmp, но с учетом нулевых байтов  | 
			 
  | 
| 
			 void *memchr(void *s, int c, size_t len)  | 
			 Аналог strchr, но с учетом нулевых байтов  | 
			 
  | 
| 
			 void *memset(void *s, int c, size_t len)  | 
			 Заполняет первые len байтов массива s символом c  | 
			 
  | 
В следующем примере, использующем приведенные функции, в массиве result будет образована строка «1 января 1998 года, 12 часов».
Пример
char result[100];
char* date = «1 января 1998 года»;
char* time = «12 часов»;
strcpy(result, date);
strcat(result, «,»);
strcat(result, time);
Как видно из этого примера, литералы можно непосредственно использовать в выражениях.
Определить массив строк можно с помощью следующего объявления:
char* StrArray[5]={«one»,«two»,«three»,«four»,«five»};
