Слайд 2
3.1. Стандартная библиотека
char *strcat(char *s1, const char *s2)
char
*strncat(char *s1, const char *s2, size_t n)
const char *strchr(const
char *s, int c)
const char *strrchr(const char *s, int c)
int strcmp(const char *s1, const char *s2)
int strncmp(const char *s1, const char *s2, size_t n)
char *strcpy(char *s1, const char *s2)
char *strncpy(char *s1, const char *s2, size_t n)
Слайд 3
3.1. Стандартная библиотека
size_t strcspn(const char *s1, const char
*s2)
size_t strspn(const char *s1, const char *s2)
size_t strlen(const char
*s)
const char *strpbrk(const char *s1, const char *s2)
const char *strstr(const char *s1, const char *s2)
char *strtok(char *s1, const char *s2)
Слайд 4
3.2. Ввод строки
gets(char *) – ввод строки вместе
с кодом ‘\n’;
не контролирует размер памяти
scanf(“%Ls”, buf)
– ввод стоки длиной не более L символов (размер памяти – L + 1);
не вводит пробелы и символ ‘\n’
scanf(“%L[^\n]”, buf) – ввод строки длиной не более L символов
вводит любые символы
во входном потоке остается ‘\n’
Слайд 5
3.2. Ввод строки
char buf[L + 1], c;
int n;
n = scanf(“%L[^\n]%c”, buf, &c);
позволяет удалить из
входного потока символ ‘\n’
Слайд 6
3.3. Варианты ввода данных
n = scanf(“%L[^\n]%c”, buf, &c);
1.
Вводится пустая строка
входной поток:
Результат:
n = 0
buf и c не
меняют своего содержимого
входной поток:
Слайд 7
3.3. Варианты ввода данных
n = scanf(“%L[^\n]%c”, buf, &c);
2.
Вводится срока длиной k
2
buf:
входной поток:
c
c
. . .
k
c
c
. . .
k
\n
\0
с:
Слайд 8
3.3. Варианты ввода данных
n = scanf(“%L[^\n]%c”, buf, &c);
3.
Вводится строка длиной k > L
входной поток:
Результат:
n = 2
buf:
входной
поток:
c
c
. . .
L
x
y
. . .
k
c
c
. . .
L
\0
x
y
. . .
с:
Слайд 9
3.4. Алгоритм ввода
цикл {
ввести строку: n =
scanf(. . .);
анализ n:
n == -1:
освободить
память, результат = NULL
n == 0:
удалить из входного потока ‘\n’
Слайд 10
3.4. Алгоритм ввода
n == 2:
проверить
c == ‘\n’
да – присвоить n = 0;
нет –
вернуть c в поток
сформировать результирующую строку
} пока n > 0
Слайд 11
3.5. Коррекция входного потока
n = scanf(“%L[^\n]%c”, buf, &c);
ungetc(c,
stdin);
входной поток:
Результат:
buf:
входной поток:
c
c
. . .
L
x
y
. . .
k
c
c
.
. .
L
\0
x
y
. . .
x
с:
Слайд 12
3.6. Формирование строки
char *ptr = (char *)malloc(1);
int len
= 0;
*ptr = ‘\0’;
n = scanf(“%L[^\n]%c”, buf, &c);
len +=
strlen(buf);
ptr = (char *)realloc(ptr, len + 1);
strcat(ptr, buf);
Слайд 13
3.7. Реализация алгоритма
char *getstr()
{
char *ptr = (char *)malloc(1);
char
buf[81];
char c;
int n, l = 0;
*ptr = '\0';
do{
n =
scanf("%10[^\n]%c", buf, &c);
if(n < 0){
free(ptr);
ptr = NULL;
}
else
Слайд 14
3.7. Реализация алгоритма
if(n == 0)
scanf("%c", &c);
else {
if(c ==
'\n')
n = 0;
else
ungetc(c, stdin);
l += strlen(buf);
ptr = (char *)
realloc(ptr, l + 1);
strcat(ptr, buf);
}
} while(n > 0);
return ptr;
}
Слайд 16
4.1. Определение структуры
struct имя_структуры {
тип имя, …
;
тип имя, … ;
. . .
};
struct Point {
double x, y;
};
Слайд 17
4.2. Определение переменных
struct имя_структуры имя_переменной
= {
значение_1, значение_2, . . .} ;
struct
Point p1 = {1.25, -3.8}, p2;
Слайд 18
4.3. Определение массива
struct имя_структуры имя_массива[количество]
{значение_01,
значение_02, . . . },
{значение_11,
значение_12, . . . },
. . .
} ;
struct Point pp[3] =
{{1, 1}, {2,2}, {1,2}};
= {
Слайд 19
4.4. Операции со структурами
struct Point p1 =
{1.5, 2.8};
Копирование структуры
struct Point p2 = p1;
Присваивание структуры
struct
Point p3;
p3 = p1;
Разыменование структуры
p1.x . . . p1.y . . .
1.5
2.8
x
y
p2
1.5
2.8
x
y
p3
Слайд 20
4.5. Вложенные структуры
struct Point {
double x,y;
};
struct
Circle {
struct Point center;
double rad;
};
struct Circle
c = {{1, 0}, 2};
x
y
rad
center
c
.
center
y
.
Слайд 21
4.6. Указатели на структуру
struct Point {
double
x, y;
};
struct Point p1 = {1.5, 2.8};
struct
Point *ptr
Разыменование структуры:
ptr
(*ptr)
.
x
ptr
−>
x
= &p1;
Слайд 22
4.7. Списки
Элемент списка
struct Item {
тип info;
struct Item *next;
};
Начало списка
struct Item *first;
Слайд 23
4.8. Примеры работы со списком
Создать список из символьной
строки
Вывести список в выходной поток
Освободить память, занятую списком
Слайд 24
4.8.1. Объявления
#include
#include
struct Item {
char c;
struct
Item *next;
};
struct Item *creatList(const char *);
void putList(struct Item *);
struct
Item *deleteList(struct Item *);
Слайд 25
4.8.2. Функция createList()
struct Item *creatList(const char *str)
{
struct
Item head = {'*', NULL};
struct Item *last = &head;
while(*str
!= '\0'){
last->next = (struct Item *)malloc(sizeof(struct Item));
last = last->next;
last->c = *str++;
last->next = NULL;
}
return head.next;
}
Слайд 26
4.8.3. Функция putList()
void putList(char *msg, struct Item *ptr)
{
printf("%s:
\"", msg);
for(; ptr != NULL; ptr = ptr->next)
printf("%c", ptr->c);
printf("\"\n");
}
Слайд 27
4.8.4. Функция deleteList()
struct Item *deleteList(struct Item *ptr)
{
struct Item
*tmp = NULL;
while(ptr != NULL){
tmp = ptr;
ptr = ptr->next;
free(tmp);
}
return
ptr;
}
Слайд 28
4.8.5. Тестирование
int main()
{
char buf[80];
struct Item *st;
while(puts("enter string"), gets(buf)){
st
= creatList(buf);
putList("Entered string", st);
st = deleteList(st);
}
return 0;
}
Слайд 29
4.9. Задача
Из входного потока вводится произвольное число текстовых
строк; конец ввода – конец файла. Длина каждой строки
также произвольна.
Каждая строка представляет собой последовательность слов, разделенных пробельными символами.
Получить новую строку, оставив в исходной ее каждое второе слово.
Строка представлена списком.
Слайд 30
4.10. Структура программы
Функция main()
Функция ввода строки произвольной длины
Функции
создания списка, удаления списка и вывода списка в поток
Функция
формирования результирующей строки
Функции удаления пробелов, удаления слова, пропуска слова
Слайд 31
4.10. Структура программы
main
Ввод строки
Формиро-вание списка
Реоргани-зация списка
Вывод списка
Удаление
списка
Пропуск слова
Удаление слова
Удаление пробелов
Слайд 32
4.10.1. Функция main()
typedef struct Item{
char c;
struct Item *next;
} Item;
int main()
{
Item *p
= NULL;
Слайд 33
4.10.2. Функция main()
while(puts("enter..."), getstr(&p) == 0){
putList("Source string", p);
p = reorg(p);
putList("Result string", p);
p = delList(p);
}
puts("That's all. Bye!");
return 0;
}
Слайд 34
4.11. Реорганизация списка
Удалить лидирующие пробелы
Список пуст
начало
конец
1-ое слово
Удалить
слово
Пропустить слово
да
да
нет
нет
Слайд 35
4.11.1. Реализация
Item *reorg(Item *p)
{
Item head =
{'\0', p},
*last = &head,
*prev = NULL;
int f = 0;
while(last && (last->next = delSpace(last->next))){
f = !f;
Слайд 36
4.11.2. Реализация
if(f)
last->next = delWord(last->next);
else{
prev = skipWord(last->next);
last = prev->next;
if(last)
last->c = ' ';
} // else
} // while