864.00K
Category: programmingprogramming

Строки. Тема 8

1.

Тема 8. Строки
1

2.

Строки
Примеры определения и инициализации строк:
1.
char s1[]={'s','t','r','i','n','g','1','\0'};
//выделено и заполнено 8 байт
char s2[] = "string2"; //выделено и заполнено 8 байт
2.
3.
char s3[10] = "string3"; //выделено 10 байт, а
заполнено 8 байт
4.
char *s4 = "string4"; //выделено и заполнено 8 байт
5.
char *s5 = new char [11];
for (int i=0;i<10;i++)
s5[i]= ' ';
s5[10]='\0';
2

3.

Строки
В С++ есть два вида строк: С-строки и класс стандартной библиотеки С++ string.
С-cтрока – это массив символов, заканчивающийся нуль-символом (символом с кодом 0, что
записывается в виде управляющей последовательности '\0'). Класс string более безопасен в
использовании, чем С-строки, но и более ресурсоемок. Для грамотного использования этого класса
требуется знание объектно-ориентированного программирования, поэтому он будет рассмотрен
позднее, а пока рассмотрим С-строки.
Память под строки, как и под другие массивы, может выделяться как компилятором (статическое
выделение памяти), так и с помощью специальных функций на этапе выполнения программы
(динамическое выделение памяти). Длина динамической строки может быть переменной и
задаваться на этапе выполнения программы, а длина не динамической строки только константой.
Удобно задавать длину строки с помощью именованной константы, поскольку такой вариант, вопервых, лучше читается, а во-вторых, при возможном изменении длины строки потребуется
изменить программу только в одном месте. При задании длины строки необходимо учитывать
завершающий нуль-символ. Например, в строке str можно хранить не 80, а только 79 символов.
Строки можно при описании инициализировать строковыми константами, при этом нуль-символ в
позиции, следующей за последним заданным символом, формируется автоматически.
Если строка при определении инициализируется, ее размерность можно опускать (компилятор сам
выделит соответствующее количество байт).
Инициализация динамических строк выполняется, либо в цикле посимвольно (включая и нульсимвол), либо с помощью библиотечных функций работы со строками.
str4 - указатель на строковую константу, изменить которую невозможно.
3

4.

Строки
Способы ввода/вывода строк :
С помощью объекта cin и операции ввода >>
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{ const int n = 80;
char s[n];
cout << "s : ";
cin >> setw(80) >> s;
cout << s << endl;
}
4

5.

Строки
Вводить и выводить строки можно различными способами.
Можно вводить строки с помощью объекта cin и операции ввода >>.
Как видно из примера, при вводе строки, состоящей из нескольких слов, выводится только первое
слово. Это происходит из-за того, что ввод выполняется до первого пробельного символа (пробела,
знака табуляции или символа перевода строки \n).
Если во вводимой строке больше символов, чем может вместить выделенная для ее хранения
область памяти, то программа завершиться аварийно. Использование манипулятора setw(80)
позволяет избежать переполнение буфера, отведенного под строку, поскольку ограничивает
количество вводимых символов числом в скобках.
5

6.

Строки
Способы ввода/вывода строк :
С помощью объекта cin и методов getline() или get()
#include <iostream>
using namespace std;
int main()
{ const int n = 80;
char s[n];
cout << "s : ";
cin.getline(s,n);
cout << s << endl << endl;
cout << "s : ";
cin.get(s,n);
cout << s << endl;
}
6

7.

Строки
Если требуется ввести строку, состоящую из нескольких слов, в одну строковую переменную,
используются методы getline или get класса istream, объектом которого является cin. Позже мы
изучим, что такое класс и его методы, а пока просто будем пользоваться ими. Здесь важно знать
синтаксис вызова метода – после имени объекта ставиться точка, а затем записывается имя
метода.
Метод getline считывает из входного потока (n-1) символов или менее, если символ перевода
строки встретился раньше, и записывает их в строковую переменную s. Символ перевода строки
также считывается (удаляется) из входного потока. Вместо символа перевода строки в строковой
переменной размещается завершающий 0.
Метод get работает аналогично, но оставляет в потоке символ перевода строки. В строковую
переменную добавляется завершающий 0.
Замечание. Типичная ошибка: нельзя обращаться к методу get с двумя аргументами два раза
подряд, не удалив ‘\n’ из входного потока.
7

8.

Строки
#include <iostream>
using namespace std;
int main()
{ const int n = 80;
char s[n];
cin.get(s,n);
cin.get();
cout << s << endl;
cin.get(s,n);
cin.get();
cout << s << endl;
cin.get(s,n);
cin.get();
cout << s << endl;
cin.get(s,n);
cin.get();
cout << s << endl;
cout << "The end!" << endl;
}
8

9.

Строки
Замечание. Типичная ошибка: нельзя обращаться к методу get с двумя аргументами два раза
подряд, не удалив ‘\n’ из входного потока.
После ввода первой строки метод get «встретит» символ ‘\n’ , оставленный во входном потоке
после первого вызова этого метода. В результате на экран будут выведены еще три пустые строки,
а символ ‘\n’ так и останется во входном потоке. Это символ надо удалить из потока путем вызова
get без параметров.
Метод getline после прочтения строки не оставляет во входном потоке символ ‘\n’ , поэтому лучше
пользоваться им.
9

10.

Строки
Способы ввода/вывода строк :
С использованием функций ввода/вывода языка С
#include <stdio.h>
int main()
{ const int n = 80;
char s[n];
gets(s); puts(s);
}
#include <stdio.h>
int main()
{ const int n = 80;
int a; float b;
char s[n];
puts(" s : "); gets(s);
printf("a = "); scanf("%d",&a);
printf("b = "); scanf("%f",&b);
printf("%2d%25s%5.1f\n",a,s,b);
}
10

11.

Строки
Очень удобный способ ввода-вывода строк – использование функций языка С gets и puts.
Вывод при помощи функции printf удобнее использовать в том случае, если в одном операторе
требуется вывести данные различных типов. Если же работа выполняется только со строками, то
следует использовать puts.
11

12.

Строки
Основные библиотечные функции для обработки строк в
стиле С ( объявлены в файле string.h).
unsigned strlen(char* s)
int *strcmp(char* s1, char* s2)
char *strchr(char* s, int ch)
char* strstr(char* s1 char* s2)
char* strcpy(char* s1, char* s2)
char* strcat(char* s1, char* s2)
char* strtok(char* s1, char* s2)
12

13.

Строки
Использование функций копирования
#include <iostream>
#include <string.h>
using namespace std;
int main()
{ char x[]= "The string C++"; char y[50],z[15];
cout << " x : " << x << endl;
cout << " y : " << strcpy(y,x) << endl;
strncpy(z,x,10); z[10] = '\0';
cout << " z : " << z << endl;
}
13

14.

Строки
Функция strcpy(y,x ) – копирует строку х в y, включая завершающий нулевой символ.
Функция strncpy(z, x, n) – копирует не более чем n символов массива x в z.
Если x – это строка длиной меньше, чем n, то в z дописывается нулевой символ столько раз,
сколько нужно, чтобы общее количество скопированных символов равнялось n.
14

15.

Строки
Использование функций объединения строк
#include <iostream>
#include <string.h>
using namespace std;
int main()
{ char s1[50]= "C++ "; char s2[] = "in samples and tasks";
char s3[50]=" ";
cout << "s1 = " << s1 << endl << "s2 = " << s2 << endl;
cout << "strcat(s1,s2) = " << strcat(s1,s2) << endl;
cout << "strncat(s3,s1,14) = " << strncat(s3,s1,14) << endl;
}
15

16.

Строки
Функция strcat(s1,s2 ) – добавление копии строки s2, включая завершающий нулевой символ, в
конец строки s1. Начальный символ строки s2 записывается поверх нулевого символа в конец
строки s1.
Функция strncat(s1, s2, n) – добавляет не более чем n символов массива s2 в конец строки s1.
16

17.

Строки
Сравнение строк
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
cout << "\n Abc and Abc
cout << "\n abc and Abc
cout << "\n abcd and abc
cout << "\n Abc and Abcd
cout << "\n abcd and abce
cout << "\n Abce and Abcd
cout << "\n Abc and abc
cout << "\n ABc and abd
cout << endl;
}
"
"
"
"
"
"
"
"
<<
<<
<<
<<
<<
<<
<<
<<
strcmp("Abc","Abc");
strcmp("abc","Abc");
strcmp("abcd","abc");
strcmp("Abc","Abcd");
strcmp("abcd","abce");
strncmp("Abce","Abcd",2);
stricmp("Abc","abc");
strnicmp("ABc","abd",2);
17

18.

Строки
Функция strcmp(s1,s2 ) – возвращает 0, если строки равны, отрицательное значение, если первая
строка меньше, чем вторая, и положительное значение, если первая строка больше, чем вторая.
Функция strncmp(s1,s2 ) – используется для сравнения только первых n символов двух строк.
Функции stricmp(s1,s2 ) и strnicmp(s1,s2 ) используются для сравнения строк без учета регистра, т.
е. без различия между прописными и строчными буквами.
18

19.

Строки
Определение длины строки и разделение строки на лексемы (слова)
#include <iostream>
#include <string.h>
using namespace std;
int main()
{ char string[]= "This sentence;has-5 words.";
char * tokenPtr;
cout << "\n string :" << endl << string;
cout << "\n length string :" << strlen(string);
cout << "\n words :" << endl;
tokenPtr = strtok(string, " ;-.");
while (tokenPtr != NULL)
{ cout << tokenPtr << endl;
tokenPtr = strtok(NULL," ;-.");
}
}
19

20.

Строки
Рассмотрим пример определения длины строки и разбиения строки на лексемы (слова).
Функция strlen() возвращает длину строки (без учета символа завершения строки).
Для разбиения строки на лексемы (слова) используется последовательность вызовов функции
strtok () .
Функция strtok () возвращает из строки string следующую лексему, отделенную любым
разделителем.
tokenPtr – указатель, ссылающийся на следующий символ, начиная с которого должен
осуществляться поиск следующей лексемы.
Каждый последующий вызов функции с нулевым указателем в качестве значения первого
аргумента продолжает поиск лексем, начиная с того места в строке, на которое указывает
возвращенное в результате последнего вызова значение указателя.
Функция strtok () возвращает нулевой указатель, если лексемы не обнаружены.
20

21.

Строки
Библиотечные функции обработки символов (ctype.h)
Прототип
Описание функции
int isdigit(int С)
Возвращает true, если элемент С является цифрой,
в противном случае false (0).
int isalpha(int С)
Возвращает true, если элемент С является буквой,
в противном случае false (0).
int isalnum(int С)
Возвращает true, если элемент С является цифрой
или буквой, в противном случае false (0).
int isxdigit(int С) Возвращает true, если элемент С является
шестнадцатеричной цифрой, в противном случае
false (0).
int islower(int С)
Возвращает true, если элемент С является
строчной буквой, в противном случае false (0).
Только для латинских букв.
int isupper(int С)
Возвращает true, если элемент С является
прописной буквой, в противном случае false (0).
Только для латинских букв.
21

22.

Строки
Прототип
Описание функции
int tolower(int С)
Если элемент букв С является прописной буквой, то
возвращается элемент С как строчная буква, в
противном случае функция возвращает аргумент
без изменений. Только для латинских букв.
int toupper(int С)
Если элемент букв С является строчной буквой, то
возвращается элемент С как прописная буква, в
противном случае функция возвращает аргумент
без изменений. Только для латинских букв.
int isspase(int С)
Возвращает true, если элемент С является
разделителем: переход на новую строку, пробел,
переход на новую страницу, горизонтальная и
вертикальная табуляция, в противном случае false
(0).
int iscntrl(int С)
Возвращает true, если элемент С является
управляющим символом, в противном случае false
(0).
22

23.

Строки
Прототип
Описание функции
int ispunct(int С)
Возвращает true, если элемент С является
символом пунктуации, отличным от пробела, цифры
или буквы, в противном случае false (0).
int isprint(int С)
Возвращает true, если элемент С является любым
печатным символом, включая пробел, в противном
случае false (0).
int isgraph(int С)
Возвращает true, если элемент С является
печатным символом, отличным от пробела, в
противном случае false (0).
23

24.

Строки
Библиотечные функции преобразования строк (stdlib.h)
Прототип
Описание функции
double atof(const char *S) Преобразует строку S в число типа double
int atoi(const char *S)
Преобразует строку S в число типа int
long atoi(const char *S)
Преобразует строку S в число типа long int
24

25.

Строки
Функции поиска из библиотеки обработки строк (string.h)
Прототип
Описание функции
char* strchr(const char
*S, int C)
Определяет позицию первого вхождения
символа С в строку S. Если его нет, то
возвращается указатель NULL
char* strstr(const char
*S1, const char *S2)
Определяет позицию первого вхождения в
строку S1 подстроки S2. Если подстрока не
найдена, то возвращается указатель NULL
size_t strcspn(const char
*S1, const char *S2)
Определяет и возвращает длину начальной
части строки S1, состоящей из символов,
не содержащихся в строке S2.
size_t strspn(const char
*S1, const char *S2)
Определяет и возвращает длину начальной
части строки S1, состоящей только из
символов, содержащихся в строке S2.
size_t strpbrk(const char
*S1, const char *S2)
Определяет позицию первого вхождения в
строку S1любого из символов строки S2.
Если символ не найден, то возвращается
указатель NULL
25

26.

Строки
Примеры использования функций поиска из библиотеки обработки
строк (string.h)
#include <iostream>
#include <string.h>
using namespace std;
int main()
{ // использование strchr
char *str ="This is a text";
char ch1 = 's', ch2 = 'o';
cout << endl << "ch1 = " << ch1 << " ch2 = " << ch2 << endl;
if (strchr(str, ch1) != NULL)
cout << "ch1 is in " << "\"" << str << "\"" << endl;
else
cout << "ch1 is not in " << "\"" << str << "\"" << endl;
if (strchr(str, ch2) != NULL)
cout << "ch2 is in " << "\"" << str << "\"" << endl;
else
cout << "ch2 is not in " << "\"" << str << "\"" << endl;
}
26

27.

Строки
Примеры использования функций поиска из библиотеки обработки
строк (string.h)
#include <iostream>
#include <string.h>
using namespace std;
int main()
{ // использование strcspn и strspn
char *str1 = "The value is 3.14159";
char *str2 = "3.14159 is the value";
char *str3 = "1234567890";
cout <<endl <<"str1 = "<< str1 <<" str3 = " <<str3 << endl;
// длина начальной части строки str1, не содержащая
// символов из str2, равна
cout << " - " << strcspn(str1,str3) << endl;
cout <<endl <<"str2 = "<< str2 <<" str3 = " <<str3 << endl;
// длина начальной части строки str1, содержащая только
// символы из str2, равна
cout << " - " << strspn(str2,str3) << endl;
}
27

28.

Строки
Примеры использования функций поиска из библиотеки обработки
строк (string.h)
#include <iostream>
#include <string.h>
using namespace std;
int main()
{ char *str = "This is a text";
// использование strpbrk
char *str2 = "pink";
char *str3 = "is a";
cout <<endl <<"str = "<< str <<" str2 = " <<str2 << endl;
// среди символов строки str2 первый, встречающийся
// в строке str
cout << " - " << strpbrk(str,str2) << endl;
// использование strstr
cout <<endl <<"str = "<< str <<" str3 = " <<str3 << endl;
cout << " - " << strstr(str,str3) << endl;
}
28

29.

Строки
Пример 1:
/* Дана строка символов, состоящая из слов. Слова
разделяются пробелом. Удалить из строки все слова,
начинающиеся с цифры.*/
#include <stdio.h>
#include <string>
#include <ctype.h>
using namespace std;
int main(void)
{ char s[250], //исходная строка
w[25],
//слово
mas[10][25]; //массив слов
int k=0,t=0,i,len,j;
puts("\n Введите строку");
gets(s);
len = strlen(s);
29

30.

Строки
while(t<len)
{ for(j=0,i=t; s[i]!= ' '; i++, j++)
w[j] = s[i];
//формируем слово до пробела
w[j] = '\0';
//формируем конец строки
strcpy(mas[k],w); //копируем слово в массив
k++; //увеличиваем счетчик слов
t=i+1; //переходим к следующему слову в исходной строке
}
strcpy(s,""); //очищаем исходную строку
for(t=0; t<k; t++)
if(!isdigit(mas[t][0])) //если символ не цифра
{ strcat(s,mas[t]); //копируем в строку слово
strcat(s," ");
//копируем в строку пробел
}
puts(s); //выводим результат
}
30

31.

Строки и функции
!
• строки передаются в функции так же, как и массивы;
Задача: составить функцию, которая переставляет символы
строки в обратном порядке.
Алгоритм:
• определить длину строки ;
• все символы первой половины строки переставить с
соответствующими символами второй половины:
s[i]
s[len-1-i]
31

32.

Строки и функции
Программа:
#include <conio.h>
#include <string>
using namespace std;
void Reverse ( char s[])
{ int len = strlen(s);
char c;
for ( int i = 0; i < len/2; i ++ )
{ c = s[i]; s[i] = s[len-i-1]; s[len-1-i] = c; }
}
int main()
{ char s[] = "0123456789";
Reverse(s); puts(s);
Reverse(s + 5); puts(s); // инверсия части строки
}
32

33.

Строки и текстовые файлы
Контрольные вопросы
1.
2.
3.
4.
Понятие строки в языке С. Примеры определения и инициализации строк.
Способы ввода-вывода строк.
Основные библиотечные функции для обработки строк, примеры их
использования.
Как передаются строки в качестве параметра в функцию?
33
English     Русский Rules