Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Практикум по основам программирования. Массивы. Строки. Подпрограммы. Учебное пособие
.pdf
Пример определения переменной строкового типа (строки):
char s[10];
char word[ ] = {′a′,′b′,′c′,′d′,′\0′};
char stroka[ ] = "ABCDEF";
В первом примере определен массив из 10 элементов типа char.
Для использования такого массива в качестве строки нужно при задании значений элементам этого массива одному из элементов присвоить
значение символа ′\0′.
Например:
char c, i = 0;
scanf("%c", &c);
while (c != ′,′)
{
s[i++] = c;
scanf("%c", &c);
}
s[i] = ′\0′;
Читая последовательность символов, помещаем очередной символ
в массив s, пока не введем символ ′,′. После ввода символа ′,′ и выхода
из цикла добавляем к символам в массиве s символ ′\0′- признак конца
строки. Максимальная длина последовательности символов в строке s
– 9 символов (10-й символ это ′\0′).
Во втором примере определен и инициализирован массив word из
пяти символов, последним из которых является признак конца строки.
В третьем примере определен и инициирован массив stroka из 7
символов, последним из которых также является символ ′\0′, так как
массив инициирован строковой константой "ABCDEF" (символ ′\0′ всегда завершает строковую константу). Количество элементов в массиве
(во втором и третьем примерах) определяет компилятор по числу начальных значений в списке инициализации.
31

Так как строковый тип – это одномерный массив символов, допол-
ненный специальным символом, то для строки сохраняются все свойства регулярного типа (т. е. над отдельными элементами можно выполнять операции, допустимые для базового типа). С «нуль-символом»
можно работать, как и с остальными символами (не забывая, о его основном назначении).
Кроме этого, для строк определен набор стандартных функций.
Функции работы со строками позволяют обрабатывать строку как единое значение. Для использования функций работы со строками надо
подключить к программе файл string.h.
Представление текста в оперативной памяти
Исходный текст – это, как правило, последовательность символов,
состоящая из слов, разделенных символами-разделителями и оканчивающаяся символом-признаком конца текста. При выборе структуры
данных для отображения текста в оперативной памяти надо стремиться
к тому, чтобы текст занимал минимально необходимый объем памяти,
и выбранная структура предоставляла средства для быстрого (непосредственного) обращения к элементам текста, которыми, как правило,
являются его слова. Таким требованиям отвечает структура данных –
массив. Текст можно представить:
1) Массивом с элементом строкового типа, представляющим сло-
во текста. Размер строки равен максимальной длине слова плюс
один (символ ′\0′). Количество элементов массива равно максимальному числу слов в тексте. Обращение к элементу массива –
это обращение к слову. Для создания такой структуры нужно
читать текст посимвольно, помещая каждое очередное слово в
новую строку массива с добавлением к слову символа ′\0′ или
пословно.
32

Пример задания последовательности слов:
Дана последовательность, содержащая от 1 до 10 слов, в каждом из
которых от 1 до 7 строчных латинских букв. Представить такую последовательность можно:
char text1[10][8], k;
Так как количество слов является меняющейся величиной (от 1 до
10 слов), то требуется еще ввести в употребление переменную k со-
держащую фактическое количество слов. Диапазон значений k: 1 ⩽ k ⩽
10.
Либо представить:
char text2[11][8];
Здесь для возможности определения фактического наличия слов
используется дополнительное слово, являющееся признаком конца последовательности слов. Таким признаком может являться пустое строковое значение. Обращение к слову: text1[i] (0⩽ i ⩽ k - 1), text2[j] (0⩽ j
⩽ 10). Если text2[j] ==" ", то это пустое слово – признак конца последовательности слов.
Ввод слова можно осуществлять посимвольно или использовать
функцию scanf со спецификацией преобразования %s, «нуль-символ»
добавляется к строке в этом случае автоматически. Вводимое слово во
входном файле должно завершаться символом перевод строки ′\n′ или
пробелом, который не включается в результирующую строку. Если
вводимое слово завершается каким-то другим символом, то спецификация преобразования %s записывается в виде: %[^,.], где запятая и
точка (,.) это символы, которыми может завершаться слово;
2) Одномерным массивом – строкой. Такая структура полностью
соответствует внешнему представлению текста. Размер массива равен
максимальной длине исходного текста с учетом разделителей слов.
Для обращения к слову необходимо последовательно просматривать
символы массива до обнаружения очередного символа-разделителя,
который завершает текущее слово и за которым начинается новое сло-
33

во. Так продолжаем, пока очередное слово не завершится признаком
конца строки.
Примеры
1. Определить необходимые переменные и записать последова-
тельность операторов для решения задачи: дана последовательность не
более чем из 40 латинских букв, за которыми следует пробел. Преобразовать ее следующим образом:
а) первое вхождение abc заменить на ABC;
char s [41], *r;
scanf("%s", &s);
r = strstr (s, "abc");
if (r)
{
*r = ′A′;
*(r + 1) = ′B′;
*(r + 2) = ′C′;
}
printf("%s\n", s);
б) удалить все вхождения th;
char s [41], *r;
scanf("%s", &s);
r = strstr (s, "th");
while (r)
{
strcpy (r, r + 2);
r = strstr(r, "th");
printf("\n %s ", s);
в) после каждой буквы a добавить букву s.
char s[81], *r, p[80] = " ";
34

scanf("%s", &s);
r = strchr (s, ′a′);
while (r)
{
strcpy(p, r + 1);
*(r + 1) = ′s′;
strcpy(r + 2, p);
r = strchr (r + 2, ′a′);
}
printf("%s\n", s);
2. Написать программу решения задачи: дана последовательность,
содержащая от 1 до 30 слов, в каждом из которых от 1 до 10 строчных
латинских букв; между соседними словами запятая, за последним словом – точка. Найти все слова отличные от последнего и удовлетворяющие следующему свойству:
а) длина слова максимальна;
#include < string.h >
#include <stdio.h >
#include <conio.h >
const int m = 30;
const int n = 11;
void main ( )
{
int k, i, j, l;
char A[m][n], B[m][n], max, sym = ′s′;
printf("Введите последовательность: ");
i = 0;
while (sym != ′.′)
{
scanf("%[^,.]", &A[i]);
scanf("%c", &sym);
i++;
35

}
j = -1;
for (k = i, i = 0, max = 0; i < k; i++ )
if (strcmp(A[i], A[ k -1])
{
l = strlen(A[i]);
if ( l > max)
{
max = l;
j = 0;
strcpy(B[j], A[i]);
}
else
if ( l == max)
{
j++;
strcpy(B[j], A[i]);
}
}
printf("\n");
for ( i = 0; i <= j; i++)
printf(" %s ", B[i]);
getch( );
}
б) первая буква слова входит в него еще раз;
#include < string.h >
#include <stdio.h >
#include <conio.h >
const int m = 30;
const int n = 11;
void main ( )
{
int k, i, j;
36

char A[m][n], B[m][n], sym = ′s′;
printf("Введите последовательность: ");
i = 0;
while (sym != ′.′ )
{
scanf("%[^,.] ", &A[i]);
scanf("%c ", &sym);
i++;
}
j = -1;
for (k = i, i= 0; i < k; i++ )
if (strcmp (A[i], A[ k - 1]) && strchr (A[i], A[i][0])
{
j++;
strcpy(B[j], A[i]);
}
printf("\n ");
for ( i = 0; i <= j; i++ )
printf(" %s ", B[i]);
getch ( );
}
3. Написать программу решения задачи: дана последовательность,
содержащая от 1 до 30 слов, в каждом из которых от 1 до 10 строчных
латинских букв; между соседними словами пробел, за последним словом – точка. Напечатать все слова отличные от последнего слова,
предварительно преобразовав каждое из них по следующему правилу:
а) перенести последнюю букву в начало слова;
#include <string.h>
#include <stdio.h>
#include <conio.h>
const int m = 30;
const int n = 11;
void main ( )
37

{
int k, i, j;
char A[m][n], B[n], sym = ′s′;
printf("Введите последовательность: ");
i=0;
while ( sym != ′.′ )
{
scanf("%[^ .] ", &A[i]);
scanf("%c ", &sym);
i++;
}
printf(" \n ");
for (k = i, i = 0; i < k - 1; i++)
if ( strcmp(A[i], A[k - 1]))
{
j = strlen(A[i]) - 1;
sym = A[i][j];
strcpy (B, A[i]);
strcpy(&A[i][1], B);
A[i][0] = sym;
printf(" %s ", A[i],);
}
getch( );
}
б) удалить из слова все последующие вхождения первой буквы.
#include <string.h>
#include <stdio.h>
#include <conio.h>
const int m = 30;
const int n = 11;
void main()
{
38

Наименование
функций
Описание
функций
strcat
char *strcat(char *s1, const char *s2)
– добавляет строку s2 в конец строки s1
strcmp
int strcmp(const char *s1, const char *s2)
– лексикографически сравнивает строки s1 и s2.
Результат отрицателен, если s1 < s2; равен ну-
int k, i, j, *p;
char A[m][n], B[m][n], sym = ′s′;
printf("Введите последовательность: ");
i = 0;
while ( sym != ′.′ )
{
scanf("%[^ .] ", &A[i]);
scanf("%c ", &sym);
i++;
}
printf("\n");
for (k = i, i = 0; i < k - 1; i++ )
if (strcmp(A[i], A[ k - 1])
{
p = strchr(&A[i][1], A[i][0]);
while (p)
{
strcpy(p, p + 1);
p = strchr(p, A[i][0]);
printf(" %s ", A[i],);
}
}
getch( );
}
Таблица 1. Основные функции работы со строками
39

лю, если s1 == s2; положителен, если s1 > s2
(сравнение беззнаковое)
strcpy
char *strcpy(char *s1, const char *s2)
– копирует строку s2 в строку s1
strcspn
int strcspn(const char *s1, const char *s2)
– вычисляет индекс первого символа строки s1,
который принадлежит набору символов строки
s2 (это эквивалентно длине начальной подстро-
ки s1, которая не содержит ни одного символа
из набора символов s2)
strlen
unsigned int strlen(const char *s)
– вычисляет длину строки s (в байтах, не учиты-
вая символ ‗\0‘)
strrev
сhar *strrev(char *s)
– переворачивает строку s (т. е. меняет порядок
символов на противоположный)
strspn
int strspn(const char *s1, const char *s2)
– вычисляет индекс первого символа строки s1,
который не принадлежит набору символов
строки s2 (это эквивалентно длине начальной
подстроки s1, которая содержит только символы
из набора символов s2)
strstr
char *strstr(const char *s1, const char *s2)
– поиск первого вхождения строки s2 в строку s1.
Возвращает указатель на символ, с которого начинается первое вхождение или NULL, если
вхождение не найдено
strtok
char *strtok(const char *s1, const char *s2)
– поиск в строке s1 лексем (слов), разделенных
40
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
