Обработка текстовой информации
Задачи обработки текста
Зачем нужны символьные строки?
Символьные строки
Символьные строки
Символьные строки
«Строковый» тип данных
Ввод строки
Ввод строки
Функция gets
Функция fgets
Функция scanf
Что выбрать?
Ввод строки
Вывод строки
Операции со строками
Операции со строками
Поиск символа в строке
Поиск подстроки
Пример обработки строк
Пример обработки строк
Преобразования «строка» – «число»
Функция atoi (ASCII to Integer)
Преобразования «строка» – «число»
Преобразования «строка» – «число»
Сравнение строк
Сравнение строк
Сортировка строк
Хранение текста
226.35K
Категория: ПрограммированиеПрограммирование

23 октября Лекция по ОП строки1

1. Обработка текстовой информации

Лекция 4 по дисциплине
«Основы программирования»
1

2. Задачи обработки текста

Обработка текста – это пример задачи из нечисловой предметной
области.
Обработка текста сводится к решению двух основных подзадач:
1) Поиск в некоторой заданной последовательности слов или символов
вхождения другой заданной последовательности слов или символов.
А) обнаружение вхождения (Результат поиска – да или нет);
В) позиция найденного вхождения (Результат поиска – адрес в ОП
или индекс символа, с которого начинается вхождение искомой
последовательности)
2) Редактирование последовательности слов или символов. Результат –
измененная последовательность. Задачи:
А) замена части текста на другую подпоследовательность;
В) удаление части текста;
С) включение (вставка) новой подпоследовательности.
2

3. Зачем нужны символьные строки?

Алгоритмизация и программирование, язык C++, 10 класс
3
Зачем нужны символьные строки?
char s[10];
// массив символов
▪ элементы массива – отдельные объекты
▪ сложно работать со строками переменной длины
Хочется:
• строка – единый объект
• длина строки может меняться во время работы
программы
string s;
// символьная строка
строка
© К.Ю. Поляков, Е.А. Ерёмин, 2014
http://kpolyakov.spb.ru

4. Символьные строки

Алгоритмизация и программирование, язык C++, 10 класс
4
Символьные строки
Начальное значение:
string s = "Привет!";
Присваивание:
s = "Привет!";
Вывод на экран:
cout << s;
? А если массив?
© К.Ю. Поляков, Е.А. Ерёмин, 2014
http://kpolyakov.spb.ru

5. Символьные строки

Алгоритмизация и программирование, язык C++, 10 класс
5
Символьные строки
Ввод с клавиатуры:
cin >> s;
getline ( cin, s );
Отдельный символ:
только до
пробела!
до перевода
строки (Enter)
s[4] = 'a';
! Символы в строке нумеруются с нуля!
Длина строки:
метод для объектов
int n;
типа string
...
n = s.size();
© К.Ю. Поляков, Е.А. Ерёмин, 2014
http://kpolyakov.spb.ru

6. Символьные строки

Алгоритмизация и программирование, язык C++, 10 класс
6
Символьные строки
Задача: заменить в строке все буквы 'а' на буквы 'б'.
#include <iostream>
using namespace std;
main()
{
string s;
int i;
cout << "Введите строку: ";
getline ( cin, s );
for ( i = 0; i < s.size(); i++ )
if ( s[i] == 'а' )
цикл по всем
s[i] = 'б';
символам строки
cout << s;
}
© К.Ю. Поляков, Е.А. Ерёмин, 2014
http://kpolyakov.spb.ru

7. «Строковый» тип данных

«Строковый» тип не является базовым .
Объект строкового типа (или просто «строка») – это одномерный массив,
состоящий из элементов символьного типа, последний символ массива
‘\0’ (символ с кодом 0).
При выделении памяти для строки под символ конца строки выделяется 1
байт.
Примеры описания строк:
1) char str [5]; // выделено 5 байт ОП
2) char word [ ] = {‘a’, ‘b’, ’c’, ‘\0’};
‘a’
‘b’
‘c’
‘\0’
/* при объявлении с одновременной инициализацией не обязательно
указывать количество элементов. Выделено 4 байта = количество
символов + символ конца строки*/
3) char word [ ] = “abc”; // аналогично примеру 2.
4) char stroka [6] = “123”;
‘1’
‘2’
‘3’
‘\0’
/* при объявлении c указанием количества элементов и одновременной
инициализацией выделяется столько байт, сколько указано, но
инициализируются не все*/
7

8. Ввод строки

1) Посимвольный ввод: Строка символов оканчивается ‘.’ (символов не
более 10)
const int N = 11;
//определили размер массива 10+1 (для символа ‘\0’)
char ch, stroka [N]; // описали символ и строку
int len=0; // len – переменная для подсчета количества введенных символов
scanf_s(“%c”, &ch); //ввели первый символ
while (ch!= ‘.’ && len < N-1) // пока не ввели ‘.’ , т.е. конец вводимой строки
{stroka [len] =ch; //записали символ в строку
len++;
//увеличили счетчик количества символов
scanf_s(“%c”, &ch); //ввели следующий символ
}
if (ch!= ‘.’ ) printf (“error ); //сообщение о превышении размера массива;
else stroka [len] = ‘\0’; //записали в строку признак конца ‘\0’
Вместо scanf_s (“%c”, &ch) можно использовать ch = getchar ();
8

9. Ввод строки

2) Ввод строки целиком. Признак конца строки записывается функциями
ввода автоматически.
А) const int N = 11;
сhar stroka [N];
scanf_s (“%s”, stroka, N);
// вводит символы, пока во входной последовательности не встретится
символ пробела или enter
B) const int N = 11;
сhar stroka [N];
gets (stroka);
// вводит символы, пока во входной последовательности не встретится
символ enter
Недостаток gets! Не контролируется количество введенных символов.
Возможен выход за границы массива!
9

10. Функция gets

gets()
Синтаксис:
char *gets(char *s);
Что делает: считывает строку из стандартного ввода (обычно с клавиатуры) до
символа новой строки (\n) и помещает её в массив s.
Затем добавляет в конец строки нулевой символ (\0).
Почему не рекомендуется: функция не проверяет границы буфера. Если
пользователь введёт строку длиннее, чем выделенный массив,
произойдёт переполнение буфера, что может привести к аварийному завершению
программы.
#include <stdio.h>
int main() {
string str;
gets(str);
printf("Вы ввели: %s", str);
return 0;
}
Важный нюанс: в современных компиляторах и стандартах использование `gets`
часто вызывает предупреждение о небезопасности. В некоторых средах может
потребоваться функция `gets_s`, но это не решает проблему проверки границ
буфера кардинально.
10

11. Функция fgets

Синтаксис: `char *fgets(char *str, int count, FILE *stream);`.
Что делает: считывает символы из потока `stream` (для консольного ввода с клавиатуры это `stdin`) до тех
пор, пока не встретится символ перевода строки (`\n`), не будет считано `count - 1` символов или пока не
наступит конец файла (`EOF`). После этого в массив `str` записывается считанная строка, а в конце
добавляется нулевой символ (`\0`).
Параметры:
* `str` — указатель на массив символов, куда будет записана строка.
* `count` — максимальное количество символов для считывания (последний элемент массива
зарезервирован для `\0`).
* `stream` — указатель на поток ввода (для клавиатуры — `stdin`).
Пример:```
#include <stdio.h>
int main() {
char str;
fgets(str, sizeof(str), stdin); // sizeof(str) даёт количество элементов в массиве
printf("Вы ввели: %s", str);
return 0;
}
Плюсы: функция безопасна — она не позволяет записать больше символов, чем выделено в массиве, что
защищает от переполнения буфера
Важный момент: если введена строка длиннее `count - 1` символов, `fgets` «обрежет» её, сохранив
нулевой символ в конце. Также она сохраняет символ перевода строки в строке, если он был во входном
11
потоке

12. Функция scanf

scanf() с спецификатором `%s`
Синтаксис: scanf("%s",str)
Что делает: считывает строку до первого разделителя (пробела, табуляции,
перевода строки). Если нужно ввести строку с пробелами (например, «Иван
Иванович»), этот способ не подойдёт — будет считано только первое слово
Пример:
#include <stdio.h>
int main() {
char name[48];
printf("Введите имя: ");
scanf("%49s", name); // Ограничиваем ввод, чтобы не выйти за границу
массива
printf("Привет, %s!", name);
return 0;
}
Ограничение: как и с `gets()`, важно явно указывать ширину поля, чтобы избежать
переполнения буфера.
12

13. Что выбрать?

Для безопасного ввода строки с пробелами
— однозначно fgets
Если нужно просто считать слово или число —
scanf("%s", str).
Главное правило: всегда контролируйте
размер буфера при вводе строки.
13

14. Ввод строки

Пример: Выход за границы массива при вводе строки
const int N = 5;
сhar strA [N], strB [N];
//выделили 5 байт по строку strA и 5 байт под строку srtB
gets (strA);
// введем в strA “12345”
‘1’
‘2’
‘3’
‘4’
‘5’ ‘\0’
// признак конца строки strA помещен на место первого символа
строки strB
gets (strB);
// введем в strB “abc”
‘1’
‘2’
‘3’
‘4’
‘5’
‘a’ ‘b’
‘c’
‘\0’
// строка strA потеряла признак конца. strA = “12345abc”, strB=“abc”
14

15. Вывод строки

1) Посимвольный вывод
const int N = 5;
сhar strA [N]; int i = 0;
while (strA [i] ! = ‘ \0’)
// или while (strA [i])
//выполнять вывод символов, пока символ не ‘\0’
printf (“%c”, strA [i] );
2) Вывод строки целиком
printf (“%s”, strA );
3) Вывод строки целиком
puts (strA);
15

16. Операции со строками

Алгоритмизация и программирование, язык C++, 10 класс
16
Операции со строками
Объединение (конкатенация):
string s, s1, s2;
s1 = "Привет";
"Привет, Вася!"
s2 = "Вася";
s = s1 + ", " + s2 + "!";
Срез (подстрока):
s = "0123456789";
s1 = s.substr( 3, 5 );
откуда
с какого
символа
s = "0123456789";
s1 = s.substr( 3 );
© К.Ю. Поляков, Е.А. Ерёмин, 2014
// "34567"
5
сколько
символов
// "3456789"
http://kpolyakov.spb.ru

17. Операции со строками

Алгоритмизация и программирование, язык C++, 10 класс
17
Операции со строками
Удаление:
s = "0123456789";
s.erase ( 3, 6 ); // "0129"
с какого
символа
сколько
символов
Вставка:
s = "0123456789";
s.insert( 3,"ABC" ); // "012ABC3456789"
куда
с какого
символа
© К.Ю. Поляков, Е.А. Ерёмин, 2014
что
http://kpolyakov.spb.ru

18. Поиск символа в строке

Алгоритмизация и программирование, язык C++, 10 класс
18
Поиск символа в строке
string s = "Здесь был Вася.";
int n;
n = s.find ( 'с' ); // 3
find – искать
! Вернёт -1, если не нашли!
if ( n >= 0 )
cout << "Номер символа 'c': "
<< n << endl;
else cout << "Символ не найден.\n";
© К.Ю. Поляков, Е.А. Ерёмин, 2014
http://kpolyakov.spb.ru

19. Поиск подстроки

Алгоритмизация и программирование, язык C++, 10 класс
19
Поиск подстроки
string s = "Здесь был Вася.";
int n;
n = s.find ( "Вася" ); // 11
if ( n >= 0 )
cout << "Слово начинается с s["
<< n << "]\n";
else
cout << "Слово не найдено.\n";
!
s.rfind() – поиск с конца строки!
© К.Ю. Поляков, Е.А. Ерёмин, 2014
http://kpolyakov.spb.ru

20. Пример обработки строк

Алгоритмизация и программирование, язык C++, 10 класс
20
Пример обработки строк
Задача: Ввести имя, отчество и фамилию. Преобразовать их к
формату «фамилия-инициалы».
Пример:
Введите имя, отчество и фамилию:
Василий Алибабаевич Хрюндиков
Результат:
Хрюндиков В.А.
Алибабаевич Хрюндиков
Алгоритм:
1. найти первый пробел и выделить имя
Хрюндиков
2. Запомнить 1 букву, удалить имя с пробелом из основной
строки
3. Найти первый пробел и выделить отчество
4. Запомнить 1 букву, удалить отчество с пробелом из основной
строки
5. «сцепить» фамилию, первые буквы имени и фамилии, точки,
пробелы…
Хрюндиков В.А.
© К.Ю. Поляков, Е.А. Ерёмин, 2014
http://kpolyakov.spb.ru

21. Пример обработки строк

Алгоритмизация и программирование, язык C++, 10 класс
21
Пример обработки строк
main()
{
string s, name, name2;
int n;
cout << "Введите имя, отчество и фамилию: ";
getline ( cin, s );
name = s.substr(0,1) + '.';// срез,начало имени
n = s.find(' ');
// найти пробел
s = s.substr(0,n+1 );
// удалить имя
n = s.find(' ');
// найти пробел
name2 = s.substr(0,1) + '.';// начало отчества
s = s.substr (0,n+1 );
// осталась фамилия
s = s + ' ' + name + name2;
// результат
cout << s;
}
© К.Ю. Поляков, Е.А. Ерёмин, 2014
http://kpolyakov.spb.ru

22. Преобразования «строка» – «число»

Алгоритмизация и программирование, язык C++, 10 класс
22
Преобразования «строка» – «число»
Из строки в число:
string s = "123";
int N;
N = atoi ( s.c_str() );
«12x3» → 12
// N = 123
в строку
языка Си
string s = "123.456";
float X;
X = atof ( s.c_str() );
© К.Ю. Поляков, Е.А. Ерёмин, 2014
// X = 123.456
http://kpolyakov.spb.ru

23. Функция atoi (ASCII to Integer)

Алгоритмизация и программирование, язык C++, 10 класс
23
Функция atoi (ASCII to Integer)
Синтаксис:
int atoi(const char *str);
Что делает: преобразует строку str в целое число типа int
Особенности работы:
Игнорирует начальные пробельные символы (пробелы, табуляции).
Начинает преобразование с первого символа, который может быть
цифрой, знаком «+» или «-».
Прекращает считывание при встрече первого символа, который не
является цифрой или знаком.
Возвращаемое значение: преобразованное число. Если преобразование
не удалось (строка не начинается с числа), функция возвращает 0.
Важный нюанс: если строка содержит корректное представление числа
0, atoi также вернёт 0. Это создаёт неоднозначность: невозможно
отличить случай успешного преобразования числа 0 от случая ошибки.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main() {
char *numStr = "12345";
int number = atoi(numStr);
printf("Число: %d\n", number); // Выведет: Число: 12345
return 0;
}
© К.Ю. Поляков, Е.А. Ерёмин, 2014
http://kpolyakov.spb.ru

24.

Алгоритмизация и программирование, язык C++, 10 класс
24
#include <iostream>
#include <sstream>
#include <string>
.
1
2
3using namespace std;
4
5int main(int argc, char* argv[])
6{
7
float v1 = 34.5691;
8
string s1 = "std:string example";
9
char c1[] = "pure c array";
10
int i1 = 25;
11
12
13
ostringstream out;
14
15
out<<"float - " << v1 <<endl << "this is s1 16
17"<<s1<<endl;
out << "char[] - "<<c1<<endl <<"ordinary
18
19int - " <<i1<<endl;
20
21
cout << out.str() << endl;
22
return 0;
}
© К.Ю. Поляков, Е.А. Ерёмин, 2014
http://kpolyakov.spb.ru

25.

Алгоритмизация и программирование, язык C++, 10 класс
25
Оператор вставки ( << ), который изначально включен во все
стандартные типы данных C++, отправляет байты в объект
потока вывода. Операторы вставки работают с
предопределенными "манипуляторами" — элементами,
которые изменяют формат целочисленных аргументов,
заданный по умолчанию.
© К.Ю. Поляков, Е.А. Ерёмин, 2014
http://kpolyakov.spb.ru

26. Преобразования «строка» – «число»

Алгоритмизация и программирование, язык C++, 10 класс
26
Преобразования «строка» – «число»
Из числа в строку:
! Идея: направить выходной поток в строку!
#include <sstream>
строковые потоки
ostringstream ss;
строковый поток
вывода
string s;
int N = 123;
ss << N;
s = ss.str();
// s = "123"
из потока в строку
© К.Ю. Поляков, Е.А. Ерёмин, 2014
http://kpolyakov.spb.ru

27. Преобразования «строка» – «число»

Алгоритмизация и программирование, язык C++, 10 класс
27
Преобразования «строка» – «число»
Вещественное число в строку:
ostringstream ss;
string s;
double X = 123.456;
ss.width(10);
// ширина поля
ss.precision(3); // знаков в дробной части
ss << X;
s = ss.str();
// s ="
123.456"
Научный формат:
ss.str("");
// очистка потока
ss.width(10);
// ширина поля
ss.precision(6); // знаков в дробной части
ss << scientific << X; // научный формат
s = ss.str();
// s = "1.234560E+002"
© К.Ю. Поляков, Е.А. Ерёмин, 2014
http://kpolyakov.spb.ru

28. Сравнение строк

Алгоритмизация и программирование, язык C++, 10 класс
28
Сравнение строк
Пар ? пар ? парк
Сравнение по кодам символов:
CP-1251
UNCODE
CP-1251
UNCODE
CP-1251
UNCODE
0
48
48
1
49
49
...
...
...
8
56
56
9
57
57
A
65
B
66
...
...
Y
89
Z
90
65
66
...
89
90
a
b
...
y
z
97
97
98
98
...
...
121
121
122
122
© К.Ю. Поляков, Е.А. Ерёмин, 2014
http://kpolyakov.spb.ru

29. Сравнение строк

Алгоритмизация и программирование, язык C++, 10 класс
29
Сравнение строк
А
Б
CP-1251 192 193
UNCODE 1040 1041
...
...
...
Ё
168
1025
...
...
...
Ю
Я
222 223
1070 1071
а
б
CP-1251 224 225
UNCODE 1072 1073
...
...
...
ё
184
1105
...
...
...
ю
я
254 255
1102 1103
5STEAM < STEAM < Steam < steam
steam < ПАР < Пар <
© К.Ю. Поляков, Е.А. Ерёмин, 2014
пар < парк
http://kpolyakov.spb.ru

30. Сортировка строк

Алгоритмизация и программирование, язык C++, 10 класс
30
Сортировка строк
main()
{
массив строк
const int N = 10;
string s1, S[N];
int i, j;
cout << "Введите строки: \n";
for ( i = 0; i < N; i ++for
) ( i = 0; i < N-1; i ++ )
getline ( cin, S[i] );
for ( j = N-2; j >= i; j -- )
...
if ( S[j] > S[j+1] )
cout << "После сортировки:{ \n";
s1 = S[j];
for ( i = 0; i < N; i++ )
S[j] = S[j+1];
cout << S[i] << endl;
S[j+1] = s1;
}
}
© К.Ю. Поляков, Е.А. Ерёмин, 2014
http://kpolyakov.spb.ru

31.

Функции работы со строками
Функции работы со строками находятся в <string.h>.
1) Определение длины строки: int strlen (char*);
Пример: char S []= “abc”;
int lenS = strlen (S); // lenS получит значение 3
2) Копирование строки: strcpy(char* , char* );
Пример: strcpy(st1, st2); // Копирование строки st2 в строку st1
Т.е. начиная с адреса, который записан в указателе st2 и пока не встретится
символ ‘\0’, символы копируются в строку st1.
3) Сравнение строк: int strcmp (char*, char*);
Результат равен 0, если строки равны; больше 0, если первая строка больше
второй; меньше 0, если первая строка больше второй.
Пример: char S []= “abc”, T[]= “abba”;
int rez = strcmp (S, T); // rez = 1, сравнение проходит посимвольно
//т.к. S[0]=T[0], S[1]=T[1], S[2]>T[2] , сравнение прекращается
4) Поиск символа в строке: char* strchr ( char*, char);
Пример: char S []= “abcbce”; char *p;
p= strchr ( S, ‘b’);
// p=&S[1], нашли первое вхождение символа ‘b’
p= strchr ( p+1, ‘b’); // p=&S[3], нашли следующее вхождение символа ‘b’
Больше функций работы со строками в см. методичке.
31

32. Хранение текста

Текст – последовательность символов, состоящая из слов, разделенных
символами-разделителями, и оканчивающаяся символом-признаком
конца текста.
Слово – последовательность символов без разделителей между ними.
Символы-разделители – пробел, запятая или другие.
Символ-признак конца текста – обычно точка.
Хранение текста:
1) Двумерный массив символов: char text [N] [M];
где N = максимальное количество слов в тексте,
M = максимальная длина слова + 1 (не забывать про ‘\0’)
Пример: Текст “В город пришла зима.” char text [5] [7];
text [0]= “В”, text [1]=“город “ … , text [4] в данном тексте не используется
В
У
\0
з
и
г
м
а
о
р
о
д
\0
п
р
и
ш л
а
\0
\0
32

33.

Хранение текста
2) Одномерным массивом char str [N*M];
где N = максимальное количество слов в тексте,
M = максимальная длина слова + 1 (для разделителей между словами.
Пример: Текст “В город пришла зима.” char str [35];
str[0]==‘B’, str [1]= ‘_’, str [2]=‘г’, …
В _ г
о р о д _ п р и ш л а _ з
и м а \0 …
… … …
33
English     Русский Правила