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

Практикум по основам программирования. Массивы. Строки. Подпрограммы. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
Пример определения переменной строкового типа (строки):
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
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]