Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Разработка комплексов программ на языке С для решения прикладных задач. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
12.08.2026
Размер:
828 Кб
Скачать
☆

unsigned n;

Функции манипулирования со строками позволяют решать различные типы задач:

связывание, изменение, сравнение, преобразование, копирование, поиск.

Ниже дается описание некоторых функций семейства str..., разделенных по типам решаемых задач.

Связывание (конкатенация) char *strcat (string1, string2);

Добавляет копию строки string2 в конец строки string1. char *strncat (string1, string2, m);

Добавляет копию m символов строки string2 в конец строки string1, и затем добавляет нулевой символ.

Обе функции возвращают ссылку на результат, то есть на строку string1.

Сравнение

int strcmp (string1, string2); Сравнивает string1 и string2 int stricmp (string1, string2);

Сравнивает string1 и string2, не делая отличия между прописными и строчными буквами.

int strncmp (string1, string2, m);

Производит такое же сравнение, как и stricmp, но просматривает не более, чем m символов.

int strnicmp (string1, string2, n);

Сравнивает string1 и string2 (но не более, чем n байтов), не делая отличия между прописными и строчными буквами.

Все функции сравнения возвращают целое значение, меньшее, равное или большеенуля, в зависимости от результата лексикографического сравнения string1 со string2.

Копирование

сhar *strcpy (string1, string2);

21

Копирует string2 в строку string1 и останавливается после пересылки нулевого символа.

char *strncpy (string1, string2, m);

Копирует точно m символов из string2 в string1, усекая или заполняя нулевыми знаками string1, если это необходимо. Если длина строки string2 больше или равна m, результирующая строка не заканчивается нулевым знаком.

Обе функции возвращают ссылку на результат, то есть string1. Функции не проверяют, умещается ли вторая строка в первой.

Поиск

int strlen (string1);

Возвращает число знаков в строке string1; нулевой знак, завершающий строку, не включается в это число.

char *strchr (string1, c); char *strrchr (string1, c);

Функция strchr (strrchr) возвращает указатель на первое (последнее) вхождение символа "c" в строку string1; если знак "c" не обнаружен в string1, то функция возвращает NULL. Нулевой знак, завершающий строку, является частью строки.

char *strpbrk (string1, string2);

Функция возвращает указатель на первый встретившийся

встроке string1 знак строки string2 или NULL, если в строке string1 не встретилось ни одного знака строки string2.

int strspn (string1, string2); int strcspn (string1, string2);

Функция strspn (strcspn) возвращает значение длины начального сегмента строки string1, целиком состоящего из знаков строки string2 (целиком состоящего из знаков, отсутствующих

встроке string2).

char *strtok (string1, string2);

Функция strtok рассматривает строку string1 как последовательность текстовых элементов (их число должно быть больше либо равно нулю), разделенных одним или более знаками из строки string2, выступающей в роли источника разделителей. Первый вызов функции (с заданным значением указателя string1

22

в качестве первого аргумента) возвращает указатель на первый знак первого элемента и записывает нулевой знак в строку string1 сразу после этого элемента.

Функция хранит информацию, необходимую для последующих вызовов (которые должны выполняться со значением первого аргумента NULL),обеспечивающих обработку строки string1 со знака, непосредственно следующего за элементом строки, обработанным во время предыдущего вызова функции. Строка-разделитель string2 меняется от вызова к вызову. После того, как исчерпаны все элементы строки string1, функция возвращает значение указателя NULL.

Изменение

char *strset (string1, ch);

Устанавливает все символы строки string1 в символы ch. char *strnset (string1, ch, n);

Заменяет первые n байт строки string1 на символы ch. Если n>strlen (string1), то strlen (string1) принимает значение n.

Примеры решений задач со строками

Пример 1. Рассмотрим пример, формирующий строку words по следующему правилу: дана произвольная строка символов dest, в строку words записать все первые символы слов строки. Словом считается последовательность символов, ограниченная пробелами или знаками препинания и не имеющая пробелов внутри себя.

#include <stdio.h> #include <stdlib.h>

int main(int argc, char *argv[])

{

char dest[200];

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

char *buf = (char*)malloc(sizeof(char*)*([strlen(dest)+1)); strcpy(buf,dest);

char *words; int k = 0;

char *temp = strtok(buf,",;.!?-");

23

while (temp!=NULL)

{

temp = strtok(NULL,",;.!?-"); k++;

}

// Если строка содержит хотя бы одно слово if (k){

/* выделить память под строку, которая будет хранить начальные символы слов */

words = (char*)malloc(sizeof(char)*(k+1)); k = 0;

// провести выделение слов вновь temp = strtok(dest,",;.!?-");

/* сохраняя первый символ каждого выделенного слова в строке words. */

words[k++] = temp[0]; while (temp!=NULL)

{

temp = strtok(NULL,",;.!?-"); if (temp)

words[k++] = temp[0];

}

/* последним символом полученной строки записать нультерминатор */

words[k] = '\0';

// вывести строку на экран puts(words);

}

system("PAUSE"); return 0;

}

Пример 2. Дана произвольная строка символов, найти слово с максимальной длиной и вывести его на экран.

#include <stdio.h> #include <stdlib.h>

int main(int argc, char *argv[]){

24

char dest[200];

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

char *buf = (char*)malloc(sizeof(char)*(strlen(dest)+1)); strcpy(buf,dest);

//Выделить первое слово строки char *temp = strtok(buf,",;.!?-");

//Принять это слово за слово с максимальной длиной int max = strlen(temp);

char *strmax = ( char*)malloc(sizeof(char)*(max+1)); strcpy(strmax,temp);

//Выделять последующие слова и сравнивать их со

//словом с максимальной длиной

while (temp!=NULL)

{

temp = strtok(NULL,",;.!?-"); if (!temp)break;

if (max<strlen(temp))

{

free( strmax);

max = strlen(temp);

strmax = (char*)malloc(sizeof(char)*(max+1)); strcpy(strmax,temp);

} }

printf("В строке %s\n слово с максимальной длиной %s", dest, strmax);

printf("\n Его длина – %d",max); free( strmax);

free( buf); system("PAUSE"); return 0;

}

Пример 3. В произвольной строке символов найти количество символов, не являющихся буквами.

Для решения этой задачи воспользуемся функцией isalpha(), которая передает ненулевое значение, если проверяемый символ

25

является буквой и нуль в противном случае. Прототип функции описан в заголовочном файле ctype.h.

#include <stdio.h> #include <stdlib.h>

int main(int argc, char *argv[]){ char dest[200];

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

int k = 0,i; for(i=0;i<strlen(dest);i++) { if(!isalpha(dest[i])) k++; }

printf("Количество символов строки, не являющихся буква-

ми – %d\n",k); system("PAUSE"); return 0;

}

2.3. Структуры

Для создания сложных типов данных в языке С используется тип данных – структура. Синтаксис описания структуры:

struct [имя] { тип поле1; тип поле2;

…

}

Такое описание называется шаблоном структуры. Имя структуры необязательный элемент. Опишем структуру, содержащую информацию о студенте (Фамилия Имя Отчество, Номер группы, Количество баллов):

struct student { char fio[31]; char group[6]; float ball;

}

26

Структура с именем student содержит три поля – массив символов (строка) для хранения фамилии (fio), строка для хранения номера группы (group), вещественная переменная для хранения количества баллов (ball).

Опишем переменную типа struct student: struct student st1; // описана переменная st1

Опишем массив структур:

struct student m_st1[22]; // описан массив m_st1

Для обращения к полям структуры используется следующий синтаксис:

<имя переменной>. <имя поля>

st1.fio – строка в поле fio переменной st1.

st1.fio[0] – первый символу поля fio переменной st1. m_st[20].fio – строка поле fio двадцатого элемента массива. Полем структуры может быть структура:

struct { struct

{

char fam[21]; char name[15]; char fname[20]; } fio;

сhar group[6]; float ball;

} st1;

В этом же примере показан другой способ описания переменной структурного типа. Обращение к полю name, переменной st1 выглядит следующим образом: st1.fio.name.

При использовании указателя на структуру обращение к полям выглядит следующим образом:

struct Coord { int x;

int y;

}

struct Coord *z;

…

27

z->y; // знак«-» и«>»

…

Вязыке С существует механизм определения собственных, пользовательских типов – typedef. В следующем примере для структуры Coord определен тип Pixel.

typedef struct

{

int x; int y;

} Pixel;

Втаком случае описание переменных будет выглядеть следующим образом:

Pixel z,m. // описаны переменные m и z.

2.4.Объединения

ВС существует тип данных, который позволяет, во-первых, хранить разнотипные данные в одной области памяти, вовторых, обращаться к частям одного целого. Например, тип int занимает в памяти 2 байта, а тип char 1 байт, используя тип union (объединение) можно обратиться к младшему или старшему байту типа int. Размер переменной такого типа определяется по полю с максимальной длиной.

Синтаксис: union [имя]

{

тип поле1; тип поле2;

…

}

Например: union massiv

{

float f; int i; char ch[2]; } elem;

28

Переменная elem занимает в памяти 4 байта, т. к. это необходимо для хранения максимального по размеру поля типа float. Необходимо помнить, что в определенный момент времени в объединении храниться только одно из указанных полей (в отличие от структуры).

Elem.f = 23.0;

Elem.i = 11; // 23.0 стирается, записывается 11 Elem.ch[0] = „c‟; // 11 стирается, записывается «с»

Elem.ch[1] = „d‟ // записывается «d»

Анализ содержимого объединения полностью ложится на программиста.

2.5. Поля битов

Битовыми полями называются элементы структуры или объединения, которые определяется как последовательность битов и описывается следующим образом. Синтаксис:

тип[имя] : длина в битах; Тип может принимать одно из следующих значений:

–int unsigned;

–int signed.

Пример: struct demo

{

int n;

unsigned a1:1; //1 бит unsigned a2:2; //2 бита double d;

signed b1:3; // 3 бита signed b2:4; // 4 бита char sh[20];

int c1:5; //5 бит int c2:6;//6 бит

}

29

Инициализируются битовые поля как обычные элементы структуры.

Пример: struct s

{

unsigned n1:1; unsigned n2:2 };

s as={0,1}; //n1=0,n2=1

Используются для установки флагов. Если надо обрабатывать только некоторые биты из поля, то остальные биты можно не нумеровать.

Пример: struct s

{

unsigned b1:1;

unsigned : 8; // не нумерованное поле unsigned b2:1;

};

Доступ к битам поля осуществляется как к обычному элементу структуры.

Пример:

void print_ints(struct demo s)

{

printf("s.a1=%d\n",s->a1); printf(...........);

}

int main()

{

demo s; s.a1=+1; s.b1=-1; s.b2=-4; print_ints(&s); return 1;

}

30

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]