
5.4. Функция main()
Основным результатом нашего проекта должна быть функция substr(). Но эта функция не может выполняться самостоятельно, она должна вызываться из какой-нибудь внешней функции. Вообще для выполнения любого программного кода, написанного на языке C, в нем должна быть функция main(). На эту функцию мы возлагаем задачи ввода данных и вывода результатов. Следовательно, чтобы заставить нашу функцию substr() выполняться и проверить ее выполнение, мы должны создать также и функцию main().
5.4.1. Переменные функции main() В функции main() должны быть объявлены переменные для:
строки-источника:
char s1[80];
строки-результата:
char s2[80];
позиции первого символа в подстроке:
int n;
длины подстроки:
int l;
того значения, которое вернет функция substr():
int r;
Пользуясь случаем, сделаем небольшое отступление, чтобы предупредить Вас про возможность ошибки, которую часто допускают начинающие программисты. Зная, что обращение к символьным строкам в языке C происходит через указатель на начало строки, такие программисты иногда объявляют символьную строку как char *. Но такое объявление, например:
char *s1;
выделяет память только для размещения указателя, но не для размещения самих символов строки. Если далее мы введем, например, 80 символов функцией gets(s1), то символы разместятся там, куда показывает указатель s1, но значение этого указателя не определено, следовательно, и символы разместятся неизвестно где. Следовательно, символьная строка обязательно должна быть объявлена как массив символов - этим выделяется для нее память, а уже обращаться к ней можно через указатель.
Не следует также забывать про необходимость резервировать в строке дополнительную позицию для признака конца строки.
5.4.2. Текст функции main() После объявления переменных текст функции main() состоит из единственного бесконечного цикла. В каждой его итерации прежде всего выводится приглашение не ввод строки-источника. Следующий оператор, возможно, требует более детального рассмотрения:
if (!strcmp(gets(s1),"***")) break;
При его выполнении прежде всего выполняется функция gets(s1), которая вводит данные в строку s1. Эта функция возвращает указатель на строку s1. Строка, на которую показывает этот указатель, сравнивается с помощью функции strcmp() со строковой константой "***". Если они равны, strcmp() возвращает 0, тогда значение логического выражения в условном операторе истинное и выполняется выход из бесконечного цикла. Следовательно, цикл будет выполняться, пока не будет введена строка "***".
Потом вводятся значения переменных n и l и выполняется вызов функции substr(), которой передаются параметры s1, s2, n, l. Значения, которое возвращает substr(), присваивается переменной r.
Строка-источник, строка-результат и возвращенное значение выводятся на экран, и цикл повторяется. (Обратите внимание на то, что при выводе символьных строк мы берем их в "скобки": >> <<. Это сделано для того, чтобы на экране можно было разглядеть символы-пробелы, которые могут быть в начале и в конце строк.)
Обращение к функции gets() в конце цикла - "технологическое". Дело в том, что функция scanf() оставляет в буфере ввода последний код клавиши Enter, которым был закончен ввод. Если не будет "технологического" gets(), то gets() в следующей итерации цикла прочитает этот символ, как пустую строку. Так что "технологическое" gets() удаляет из буфера код клавиши Enter. Чтобы убедиться, попробуйте его убрать и посмотрите, что получится.
5.4.3. Общие объявления В функции main() применяются библиотечные функции ввода-вывода и функция сравнения строк, так что включим в программу файлы stdio.h и string.h. Кроме того, следует включить и описание функции substr(). Хотя все эти описания нужны только для функции main(), стиль программирования на языке C требует размещения их в начале программы, вне программных блоков.
Полный текст программы приведен ниже.
/****************************************************/
/* Лабораторная работа ╧12 */
/* Указатели, символьные строки и функции */
/* Приклад выполнения. Вариант ╧30. */
/****************************************************/
#include <stdio.h>
#include <string.h>
int substr(char *, char *, int, int);
/*** главная функция ***/
int main(void) {
char s1[80],s2[80]; /* источник и результат */
int n, l, r; /* позиция, длина, результат */
for (;;) { /* бесконечный цикл */
printf("Введите строку >");
/* ввод строки-источника */
if (!strcmp(gets(s1),"***")) break;
/* ввод остальных параметров */
printf("Введиту pos len>");
scanf("%d %d",&n,&l);
/* обращение к функции substr() */
r=substr(s1,s2,n,l);
/* вывод результатЁв */
printf("pos=%d, len=%d\n",n,l);
printf("s1=>>%s<<\n",s1);
printf("s2=>>%s<<\n",s2);
printf("R=%d\n\n",r);
gets(s1);
}
}
/*** функция выделения подстроки ***/
/* параметры:
src - строка-источник
dest - строка-результат
pos - позиция, с которой выделяется подстрока
len - длина подстроки
функция возвращает:
0 - нормальное выполнение
1 - подстрока имеет меньшую длину, чем задано
-1 - ошибка в параметрах, результат пустой */
int substr(char *src, char *dest, int pos, int len) {
int ret; /* значение, которое возвращается */
/* выход на начальную позицию */
for(; pos&&*src; pos--, src++);
/* проверка параметров */
if (pos||(len<0)) ret=-1;
else { /* параметры корректны */
/* пересылка символов */
for(;len&&*src; *dest++=*src++,len--);
/* проверка длины результата */
ret = len ? 1 : 0;
}
/* запись признака конца в результат */
*dest=0;
return ret;
}