Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование. Лекция 5. Работа со строками.doc
Скачиваний:
1
Добавлен:
29.08.2019
Размер:
63.49 Кб
Скачать

Программирование. Лекция 5. Работа с символами и строками в С++

Из предыдущих лекций нам уже знаком символьный тип char. Описание символьных переменных имеет вид:

char a, z;

Для ввода и вывода символьных значений в форматных строках библиотечных функций printf() и scanf() используется спецификатор %c, например:

char c;

printf("Введите символ: ");

scanf("%c",&c);

printf("Вы ввели символ %с", c);

Помимо scanf() и printf() для ввода и вывода символов в библиотеке предусмотрены специальные функции обмена:

getch() – функция без параметров. Позволяет читать с клавиатуры по одному символу за обращение. Как и при использовании scanf(), чтение вводимых данных начинается после нажатия клавиши Enter.

putchar(X) – выводит символьное значение X на экран.

Пример (программа считает число значащих символов (не пробелов) в строке, которая заканчивается точкой):

char c; int n;

printf("Напишите предложение с точкой в конце:\n");

// сначала счетчик символов n равен нулю

// цикл выполняется, пока считанный с клавиатуры символ не равен точке

for (n = 0; (c = getch()) != '.'; )

{

// выводим считанный символ на экран

putch(c);

// если символ не является пробелом, увеличиваем счетчик

if (c!=' ') ++n;

}

printf("\nЧисло введенных символов (без пробелов): %d", n);

Результаты работы программы:

Напишите предложение с точкой в конце:

1 2 3 4 5

Число введенных символов (без пробелов): 5

Внутренние коды и упорядоченность символов.

Данные типа char представлены численными значениями своих внутренних кодов. Благодаря этому возможно упорядочивание символов. Следующая программа выводит на экран десятичные коды символов от 0 до 9:

char c;

for (c='0'; c < '9'; c++)

printf("Символ %c - %d\n", c, c);

Результат работы программы:

Символ 0 - 48

Символ 1 - 49

Символ 2 - 50

Символ 3 - 51

Символ 4 - 52

Символ 5 - 53

Символ 6 - 54

Символ 7 - 55

Символ 8 - 56

Таким же образом можно вывести на экран, например, коды символов от a до z (a будет иметь код 97, b – код 98, и т. д.).

Упражнение. Написать программу для вывода латинского алфавита.

Строковые константы

В программе строки представляются последовательностью символов, заключенной в кавычки, например, "Это строка".

Среди символов строки могут быть Esc-последовательности, соответствующие кодам неизображаемых символьных констант. Например, "Эта строка заканчивается переводом строки \n".

При размещении строки в памяти в ее конец автоматически добавляется символ '\0', то есть нулевой байт. За счет этого длина строки увеличивается на один байт (например, символ 'A' занимает в памяти один байт, а строка "A" – два байта).

В языке Си, в отличие от Паскаля, нет отдельного типа для строк. Строка считается массивом символов, то есть имеет тип char []. Количество элементов массива char будет на 1 больше, чем число символов в строке за счет добавления нулевого байта.

Исторически символ занимает 1 байт, в этом случае он имеет тип char. При этом существуют и другие кодировки, в которых символ представляется, например, двумя байтами. Для работы с такими строками требуются специальные функции.

Слегка отвлечемся от строк и разберем понятие кодировки. По определению, кодировка - это способ представления чего либо, в нашем случае символов. Кодировки символов делятся на однобайтные - каждый символ представлен одним байтом и многобайтные, в которых одному символу соответствует несколько байтов. В свою очередь многобайтные кодировки можно разделить на кодировки с фиксированным количеством байтов - каждому символу соответствует одинаковое количество байтов, и «плавающие», в которых один символ может представляться разным количеством байтов в зависимости от его содержимого. К первым относятся кодировки типа Unicode, в которой каждый символ представлен двумя байтами, ко вторым - UTF-8 и др.

Присвоить значение массиву символов (строке) с помощью обычного оператора присваивания нельзя! Например, следующий фрагмент кода вызовет ошибку при компиляции:

char str[10];

str = "New string";

Строку можно инициализировать:

1) при определении символьного массива, например (записываем в str строку string и посимвольно выводим ее на экран вместе с кодами символов):

char str[10] = "String";

for (int i = 0; i < 10; i++) printf("%c - %d\n", str[i], str[i]);

Результаты выполнения программы:

S - 83

t - 116

r - 114

i - 105

n - 110

g - 103

- 0

- 0

- 0

- 0

В символьный массив размерности 10 может поместиться строка не длиннее 9 символов. Так, если мы захотим записать в str[10] строку "New string", мы получим ошибку компиляции, так как не останется места для записи завершающего нулевого байта.

При инициализации символьного массива константной строкой можно не указывать размер массива, например:

char str[] = "Это новая строка";

Если инициализация не производится, размер нужно задавать обязательно, то есть строка следующего вида приведет к ошибке компиляции:

char str[];

2) С помощью функций ввода-вывода printf(), scanf(), при этом используется спецификатор %s.

char str[15];

printf ("Введите строку: ");

scanf("%s",str);

printf ("Вы ввели строку: %s ", str);

Если при выполнении этой программы пользователь введет строку длиннее 14 символов (не забываем про нулевой байт), он получит ошибку времени исполнения программы.

Есть еще один нюанс использования scanf() для чтения строк: эта функция читает строку до первого разделителя (пробела). То есть если в предыдущем примере пользователь введет строку "New string", в массив str запишется только часть строки до разделителя, то есть "New".

Обратите внимание, что при считывании строк с помощью scanf() не используется оператор взятия адреса &. Это вызвано тем, что имя массива str уже является адресом его первого элемента.

3) С использованием функции копирования строк strcpy(приемник, источник).

Пример использования функции strcpy:

char str1[10], str2[10];

strcpy(str1, "Hello");

strcpy(str2, str1);

При использовании strcpy также нужно соблюдать осторожность, так как на этапе компиляции не контролируется достаточность памяти str1 и str2 для размещения строки.

Существует функция strncpy (приемник, источник, число), которая позволяет задавать в последнем аргументе максимальное число копируемых символов. Следует заметить, что она не производит автоматическое добавление нулевого байта в конец строки. Пример использования:

char str1[10]={0}, str2[10]={0};

strncpy(str1, "Hello world",9);

strncpy(str2, str1,9);

4) с использованием функции gets(). Пример:

char s[80];

gets(s);

Функции работы со строками.

Для лексикографического сравнения строк используются функции int strcmp(строка1, строка2) и int stricmp(строка1, строка2). Первая сравнивает строки с учетом регистра, вторая – без. Все это относится только к латинице. Пример использования функции сравнения строк:

char s[80];

printf("Введите пароль: ");

gets(s);

if(strcmp(s, "pass"))

printf("Неверный пароль\n");

Для вычисления длины строки используется функция strlen (строка). Функция возвращает длину строки за вычетом нулевого байта. Эта функция полезна в случаях, если вам нужно последовательно обратиться ко всем символам строки, не нарушив при этом ее длину. Пример:

char len;

len=strlen(str);

for (i=0;i<len;i++) {

// работа со строкой, не изменяющая ее длину

}

Зачастую требуется преобразовать число в строку и наоборот. Есть несколько способов сделать это.

1) использовать функции sprintf и sscanf. Например, так:

char str[50];

int i=15;

int j;

sprintf(str, "%d", i); // Записать в str строковое представление i

sscanf(str, "%d", &j); // Записать в j число, содержащееся в строке str

sprintf(str, "i=%d and j=%d", i, j);

// содержимое str: "i=15 and j=15"

Функция int sprintf(строка, формат, [аргументы]) работает аналогично printf(), но выводит отформатированное содержимое не на экран, а в строку, указанную в качестве первого аргумента. Функция возвращает значение, равное числу символов, записанных в строку. Пример:

char buffer [50];

int n, a=5, b=3;

n=sprintf (buffer, "%d plus %d is %d", a, b, a+b);

printf ("[%s] is a %d char long string\n",buffer,n);

Функция int sscanf(строка, формат, [аргументы]) осуществляет считывание данных из строки и запись в аргументы в соответствии с форматом. Как и в обычной функции scanf(), перед аргументами ставится &.

Хотя sprintf и sscanf довольно удобны, у них есть несколько недостатков. Во-первых, они не всегда быстро работают, во-вторых не типобезопасны. Например, если в строке формата вы укажите, что передаете два целых, а вместо этого передадите два double, ошибка обнаружится только при выполнении программы и найти ее причину будет не так-то просто.

В-третьих, доступно целое семейство функций atof, atoi, atol и itoa, ltoa. Все они очень похоже между собой. Функции из первой группы преобразуют строку в число (float, int или long) в зависимости от окончания. Функции из второй группы выполняют обратное преобразование.

Пример (первый аргумент функции – число, второй аргумент – строка, третий аргумент – основание системы счисления):

char str1[5];

char str2[5];

char str3[5];

itoa(12, str1, 10); //str1=”12”

itoa(12, str1, 16); //str1=”C”

itoa(12, str1, 2); //str1=”1100”