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

Шпора по информатике, 2 семестр, Шереметьев А. И

.doc
Скачиваний:
23
Добавлен:
10.05.2014
Размер:
102.91 Кб
Скачать

Модуль utinout.c \ .h

Int TYesNoC( char *text, tc, bc );

Int TDoubleGetC( char *text, minval,maxval, typical,tc, bc, tcerr, bcerr );

Char *TStrGetC( char buf, unsigned len, tc, bc );

Int TDigitMenuC( char *menu[], tc, bc );

Системные функции

Int toupper( int ch ); - поднимает регистр всех символов

Int isspace( int c ); - если пробело подобный символ возвращает не 0

Int getchar( void ) – возвращает символ послепревращения его в int

Int getch( void ) – возвращает символ прочитанный с клавиатуры

Модуль ustring.c \ .h

Char *StrTrimL( char *s ); - убирает пробелоподобные символы слева

Char *StrTrimR( char *s); - убирает пробелоподобные символы справо

Сhar *StrTrim( char *s ); - убирает пробелоподобные символы с обоих концов

Char *StrJust( char *s, char buf[], unsigned len, int mode ) – сдвигает строку по mode

Unsigned StrMenuCalc( char *menu[], int *nol, int *nel, int *maxlen );

Считает в меню количество строк, количество пустых строк, максимальное число символов в строке.

2 наиболее распространенных способа хранения строки

2.1 начальный адрес и код концевого маркера. Код концевого маркера долен быть отличен от кода любого символа строки.

2.2 счетчик длины а после него сама строка

Системные функции

Char *strncpy( char *dst /* строка приемник */, char *scr /*строка источник*/, size_t maxlen ); - копирут строку из источника в приемник не более maxlen символов.

Модуль ufile.c \ .h ( работа с диском )

Void FDatePack( int *fdate, const int day, const int month, const int year ); - запаковывает дату в ДОС формат

Void FDateUnPack( const int fdate, int *day, int *month, int *year ); - распаковывает дату в человеческий вид

Void FTimePack( int *ftime, const int sec, const int min,const int hour);

Void FTimeUnPack( const int ftime, int *sec, int *min, int *hour );

Int biosequip( void ) – возвращает int в котором содержится информация о загрузке с диска, количество физических дисков и иная информация о системе

Int getdisk( void )- номер текущего диска

Int setdisk( int disk )- устанавливает текущим нужный диск, возвращает количество логических дисков.

Char *getcwd( char *buf, int buflen ); - заполняет буфер текущего каталога. Можно использовать MAXPATH. Ошибки:

ENODEV – нет такого устройства

ENOMEM- нет свободной памяти

ERANGE – результат слишком велик

ENOENT- путь или файл не найден

EACCES- в доступе отказано

ENMFILE – нет больше файлов

Int mkdir( char *path); - создает каталог по пути

Int rndir( char * path); - удаляет каталог ( он пуст и не корень )

Int chdir( char * path); - делает текущим указанный каталог ( все: при успехе 0\ иначе-1 )

Int getcurdir( int drv, char *dir); - пытается получить имя текущего каталога в буфер по указателю dir > MAXDIR. Путь не содержит спецификатора дисковода и не начинается с \, при успехе 0 \ инче -1.

Поиск файла

Int findfirst( const char *pathname, struct ffblk *ffblk, int attrib )- осуществляет одну попытку поиска. Pathname – строка с полным именем файла( может содержать метасимволы ).

Int findnext( struct ffblk *ffblk ); - осуществляет повторный поиск с теми же параметрами. При успехе возвращают 0 иначе ERRNO

Struct ffblk{

Char ff_reserved[21]; - зарезервировано

Char ff_atrib; - атрибут

Int ff_ftime; -время создания

Int ff_fdate; -дата создания

Long ff_fsize; -длина в байтах

Char ff_name[13]; -имя и расширение

}

FA_RDONLY - атрибуты

FA_HIDDEN

FA_SYSTEM

FA_LABEL

FA_DIREC

FA_ARCH

Формат даты: биты (0..4)-день, (5..8)-месяц, (9..15)-год начиная с 1980

Формат времени: биты (0…4)-секунды\2, (5…10)-минуты, (11…15)-часы

void fnmerge( char *path, const char *drive, const char *dir, const char *name, const char *ext )

склеивает полное имя файла из его ( диск, путь, имя, расширение )

int fnsplit( const char *path, char *drive, char *dir, char *name, char *ext ); - разбивает полное имя файла на части. Возвращает константы

EXTENTION – есть расширение, FILENAME, DIRECTORY, DRIVE, WILDCARD –в имени есть метасимволы.

Int access( const char *filename, /* полное имя файла или каталога*/

Int amode /* код доступа*/ ) – проверяет существование файла с таким именем и режим доступа к нему. 0 есл доступ разрешен, -1 если нет. 0х04- только чтение, 0х02 и 0х06 чтение и запись.

Int _chmode( const char *path, int func, [ int attrib] ) – получает или устанавливает атрибут файла имя которого задается в path. При funk == 0 возвращает текущий атрибут файла, при funk == 1 устанавливает текущий атрибут файла и приуспехе возвр. 0 иначе -1. устанавливает ERRNO.

FILE *fopen( char *filename, char *mode ); -открывает текстовый файл

FILE fclose( FILE *stream ); - закрывает текстовый файл

Int fprintf( FILE *stream, char *format , …); - печатает строку в файл

Int fscanf( FILE *stream, char *format, …); - читает строку из файла

Int fseek( FILE *stream, long offset, int whence ); - передвигает курсор по текстовому файлу, при удачи возвращает 0, иначе не 0.

Модуль utime.c \ .h ( Работа с таймером )

Void getdate( struct date *ptr ); - заполняет структуру даты системной текущей датой

Struct date {

Int da_year;

Int da_day;

Int da_mon;

}

void setdate( struct date *ptr ); - устанавливает системную дату.

void gettime( struct time *ptr ); - заполняет структуру времени

void settime( struct time *ptr ); - устанавливает системное время.

Struct time{

Unsigned char hour;

Unsigned char minute;

Unsigned char second;

Unsigned char hsecond; /* сотые доли секунды */

}

time_t time( time_t *timer ); - возвращает текущее время в секундах прошедшее с 0часов 0 минут 0 секунд и заполняет какое-то значение

int stime( time_t *tptr ); - устанавливает системное время в секундах

char *stime( const time_t *tptr ); - преобразует двоичное значение на которое указывает tptr в человеческий вид Mon_Mar_20_10:21:47_1995 – всего 26 символов. Возвращаемый указатель показывает на статические данные.

Clock_t clock( void ); - возвращает время работы процессора в тиках прошедшее с момента старта программы. 1 тик 55мс. Clock_t переменная формата long. 1 секунда 18.2 тика. Для получения времени в секундах количество тиков поделить на CLK_TCK.

Void SysDateTime( void ) /* получает системное время, устанавливает своё, просматривает и восстанавливает бывшее время */

Void WaitEnter( void ) /* измеряет время между двумя нажатиями Enter */

Void TimeInterval( void )

Модуль uvideo.c \ .h ( работа с видеопамятью )

Enum VmConst {

VmCHARS = 2;

VmXMAX = 79;

VmYMAX = 24;

VmXPOS = 80;

VmYPOS = 25;

}

начальный адрес видопамяти 0xB800 0000;

static CFP VmAddr( int x, int y ); - возвращает адрес видеопамяти для позиции x y

int VmSet( void ); - устанавливает базовый адрес видео памяти и возвращает COLOR, MONO.

Void VmPutc( x, y, ch );

Void VmPutAttr( x, y, ch, atr );

Void VmPucth( x, y, ch, attr, num );

Void VmPuts( x, y, str );

Void VmPutsa( x, y, str, attr );

Void VmFill( x, y, endx, endy, filler );

Void VmFillPaint( x, y, endx, endy, ch, atrr );

Void VmBlink( x, y, len ); - цепочка байтов мигает

Static void CursorSet( shape );

Модуль ukbrd.c \ .h ( работа с клавиатурой )

Int bioskey( int cmd); - обработка клавиш на низком уровне. При входе с cmd == 0 ожидается клавиша, если буфер клавиатуры пуст, при не пустом буфере извлекается очередной код. При входе с cmd==1 возвращает 0 если команды клавиши не было, иначе !0

Структара функции интерфейса ввода-вывода

1. анализ входной информации, инициализация и возможная коррекция.

2. цикл

2.1 подготовка области экрана к показу

2.2 установка формы и положения курсора и установка изображения

2.3 ожидание нажатия пользователем клавиши, анализ на её допустимость.

2.4 анализ допустимых команд, действия по ним.

3. вывод выходной информации.

Работа с графикой

основные режимы видеокарты

int far graphresult( void ) – возвращает код ошибки.

void far initgraph( int far *gr_driver , int far *gr_mode, char far *pathtodriver );

void far closegraph( void );

Стандартные функции работы с системным таймеров в секундах и тиках. Интерфейс и примеры использования.

1. <DOS.H>; void getdate (struct date *dptr); заполняет структура date значением текущей системной датой. struct date { int da_year; */текущий год*/; char da_date; */день месяца */; char da_mounth; */номер месяца*/}; void setdate (struct date *dptr); уст текущую сист дату по знач струк date; void gettime (struct time *tptr); void settime (struct time *tptr); struct time { unsigned char ti_min; unsigned char ti_hour; unsigned char ti_hund; unsigned char ti_sec; }; 2. <TIME.H>; time_t time(time)t *tptr); <long> возвращ текущ время в секундах прош с момента о с. 1 января 1970г. И запоминает это знач в ячейках памяти tptr; int stime (time_t *tptr) уст текущее время в tptr всегда возвр ноль. Char *ctime (time_t * tptr). Преобраз двоичное знач tptr в текстовую строку (с '/0') след форму: ‘’Mon_Mar_20_10:21:47_1995\т\0''. Данные перезапис при каждом вызове с time. Char *asc time(struct tm *tb/k);

Double difftime (time_t t2, time_t t1); возвр время в сек пром от t1 до t2; clock_t clock(void); <long> возвр время работы процессора в тиках прошедшее с момента старта программы; если время недоступно или не мб представлено в long => возвращ -1; 1 тик=55 мс (прерывание аппар таймера)= 1/18,2 сек. Отсчет от старта программы. Для получ времени знач в секундах то что возвращ clock делится. Clc_tck (=18,2). Пример измер времени выполнения участка программы. Void main (void) { clock tbeg, tend; tbeg=clock(); /* операторы, время исп кот треб измерить */ tend=clock(); printf (“\n интервал времени =%lg_ctreyl'', (double)(tend-tbeg)clk_tck);

Способы хранения строк в памяти? С концевым маркером и со счетчиком. Достоинства, недостатки, ограничения. Процедура определения длины строки. Примеры реализации. 1 сп. строка с концевым маркером. Рис 1. основное требование к коду '/0', то, что он не должен входить в алфавит символов. (в языке Си: 0x00). строка-это массив символов, оканчивающийся пустым символом ('\0'). Массивы, представляющие собой строки должны резервировать память для хранения нулевого окончания.2 сп. Строка со счетчиком. Рис 2. Оба способа взаимодополняющие. Strlen-опред длины строки. <STRING.H> <MEM.H>. рис 3.

Основные битовые операции в языке Си. Процедуры подсчета количества единичных битов в данных целого типа и вывода числа в двоичной системе счисления. Примеры реализации.Побитовые операции: 1. логические операции (побитовые операторы выполняют их одновременно с кажд битом для типов: char (8 бит), int, short, long (32 бит)); Int BitGet (int x, /* ход для чтения*/ int bit /* номер бита*/) функц возвращ знач бита bit в коде X { return (x BitMask(bit)); } <return((x BitMask/bit))?TRUE:FALSE);>. Int BitOne (intx, int bit) возвращ код x с установленным в единицу битом bit { return (x| BitMask(bit)); }. Bit zero возвращ код x со сброш в ноль битом bit. Int BitSet (intx, int bit, int val). Операция поиска бита: int BitPos o (int x) находит первый правый ноль. Возвращает номер 1ого правого нулевого бита (от 0 до 15) или возвращает 0xFFFF=-1 при входе с x равным 0xFFFF { register inti, mask; if (x==0xFFFF) return 0xFFFF; for (i=0, mask=1; x&mask;i++) mask <<1; return i; }.int BitCount возвращает кол-во единичных битов в x. Циклическая обработка. Двоичная система: 1) 1 сем. 2) void PutBin (int num) выводит на экран двоичная представл числа num (исп 'b' для представл в двоичной системе). void PutBin (int num) { int i; for (i=15; i=0; i--) if (BitGet(num,i)) putch (‘1’); else putch (‘0’); putch (‘b’) }.

Процедуры управления формой курсора и перебора строк меню в однострочном окне экрана. Примеры реализации. Способы выделения областей в текстовом экране: 1) цветом или яркостью; 2) мигание символов; 3) выдом курсора; для управления курсором выделяют: 1) выключить изображение курсора на экране 2) включить обычный курсор (короткий) 3) включить длинный крусор. Задать в константе enum CursorForms { /*внутримод константы */ SHORT=0x0607 /*короткий крусор*/ TALL=0x001F /*длинный курсор*/ HIDDEN=0x2000 /* скрытый (выкл)курсор */ }; /*---LOCAL ROUTENES---*/ static void CursorSet (int shape) получ константу и приводит к переключ курсора { union REGs r; r.h.ah=1 /* установка границ изобр курсора */ r.x.c.x=shape /*установка */ int86(0x10 (<-вызов видеодрайвера),&r,&r); } /*---PUBLIC ROUTINES---*/ void Cursor Shot (void) {CursorSet (SHORT)} void Cursor Tall (void) {CursorSet (TALL)} void Cursor HIDE (void) {CursorSet (HIDDEN)}; Управление курсором: void Cursor Pos (int x, int y) { gotoxy (x+1, y+1); } На счёт курсора: написал три типа, написал ф-цию CursorSet и три ф, которые меняют режим курсора (вызывают CursorSet).

Атрибут файла и назначение отдельных битов. Стандартные функции проверки доступа и изменения атрибутов файла.

<IO.H>; int access(char *filename /*полное имя*/ int amode /*код доступа */); проверяет на сущ файла с именем filename и режимом доступа: 0-если разрешен доступ, иначе-1; Errno: ENOEND – путь/файл не найден; EACCESS - отказ в доступе; amode: 1) 0x00-сущ; 0x01-разрешено исп; 2) 0x02-разрешена запись; 1) 0x04-разрешено чтение; 2) 0x06-разрешены чтение и запись; 1) все сущ файлы-читаемы; 2) если разрешается доступ по записи => разрешается и чтение; int_chmode (char*path, int fune[,int attrib]); int..-необязателен при fune=0 и обязателен при =1; получает или устанавливает атрибут файла, имя кот задает path; при fune=0-возвращает текущий attribute; при fune=1-устанавливает атрибут файла по коду attrib: FA_RDONLY; FA_HIDDEN; FA_SYSTEM; при успехе возвращ атрибут, иначе-1; Errno: ENOENT, EACCES; int chmed (char *filename, /*полное имя файла */ int a mode /*код доступа */); уст тип доступа к файлу filename опред символич канстантами в <SYS\STAT.H>. значение/тип доступа: 1) S_I WRITE-разреш запись; 2) S_I READ-разреш чтение; 3)4)- S_I RITEI, S_I READ- чтение+запись; Атрибуты файла — это доп инф, относящаяся к данному файлу и хранящаяся в папке. атрибут/тип файла: FA_RDONLY - 0x01 - только чтение; FA_HIDDEN - 0x02 - скрытый файл=файл не следует отображать в обычном окне папки; FA_SYSTEM - 0x04 – системный=сочетает в себе свойства атрибутов. Имеет ли в DOS смысл исполнение?- нет, существующий файл всегда исполняется. Бит/описание: 0x0001/ для файла или каталога разрешено только чтение; 0x0002/Скрытый файл или каталог; 0x0004/Системный файл или каталог; 0x0020/ Было выполнено архивирование файла; 1. получить значение опред бита в коде - BitGet; 2. установить опред бит в “1” – BitOne; 3. установить опред бит в “0” – BitZero; 4. Найти первый един бит справа – BitPos 1; 5. слева – BitPos 0; 6. подсчитать кол-во 1-битов в коде – BitCount; typedef enum bool {FALSE, TRUE} BOOL; Написать интерфейс chmod, amode и access. Перечислить коды доступа.

Стандартные функции рисования заполненных фигур в Си. Стили линий (влияют только на прямые, но не на кривые). Имя конст/смысл стиля: SOLID_LINE/сплошная; DOTTED_LINE / точечный пунктир; CENTIER_LINE/штрихопунктир (-.-.-); DASHED_LINE/(---); USER_LINE опред поль исп 16 битов каждый бит: 0/1-не/рисуется пиксель; void far setlines style (int linestyle, unsigned upatterr, int thickness). Уст атрибуты линий рисуя линию. при ошибке: graphresult=grError. Void far set write mode (int mode) уст режим рисования прямых линий. Mode=copy_put- копирование в пиксели экрана; xor_put – искл/или исп для засветки места на экране. Рисование заполненных фигур: void far elleps (intx, inty, int stangle, int endangle, int xrad, int yrad); установка стиля штриховки (заполнение): void far set fill style (int pattern, int color); USER

Функции работы с дисководами. Обработка ошибок. int biosequip(void); бит 0=1/0 – загрузка с диска/иным способом; биты 6-7 = 00 - 1 дисковод; 01 - 2 дисковода; 10 - 3 дисковода; 11 - 4 дисковода (только, если бит 0 = 1); intgetdisk (void) возвращ номер текущ логического диска /* 0-для А */ /* 1- для В */ и тд. Int setdisk(int dsk) /*устанавливается в текущем диск с кодом dsk, возвращ кол-во, имеющихся лог дисков */

1. Реализация горизонтального меню. Клавиши управления. Обработка ошибок.

1. Однострочный редактор. Клавиши управления, редактирования. Обработка ошибок.

функции открытия/закрытия видео режима, обработка ошибок..

Устройство видеопамяти. цветной и монохромный адаптер. Работа только в текстовом режиме. Несколько подвидов: вывод 25 строк по 80 символов в строке. Тип вывода/ файл/ достоинства/ недостатки/ скорость: 1. терминальный / <UTINOUT.H>/ сист функции готовые и отлаж. Переносимость на ЭВМ разной архитектуры/ самые медленные из-за модификации с файловым вводом/выводом. Утилизация файловых потоков / самая медленная. 2. консольный/ <CONIO.H>/ сист функции готовые и отлаж. Стандартизированный интерфейс для большинства современных компиляторов Си./ непереносимость (хорош только для IBM PC). Делает не все операции необх для удобного интерфейса с пользователем/ средняя. 3. прямой доступ к видеопамяти / <UVIDEO.H> /самые эффективные по скорости / только IBM PC. Их надо писать самому; Видеопамять служит для хpанения изобpажения. От ее объема зависит максимально возможное полное pазpешение видеокаpты - A x B x C, где A - количество точек по гоpизонтали, B - по веpтикали, и C - количество возможных цветов каждой точки. Hапpимеp, для pазpешения 640x480x16 достаточно 256 кб, для 800x600x256 - 512 кб, для 1024x768x64k - 2 Мб. Тк для хpанения цветов отводится целое число pазpядов, количество цветов всегда является степенью двойки (16 цветов - 4 pазpяда, 256 - 8 pазpядов, 64k – 16); Color Graphics Adapter - цветной гpафический адаптеp - пеpвый адаптеp с гpафическими возможностями. Работает либо в текстовом pежиме с pазpешениями 40x25 и 80x25 (матpица символа - 8x8), либо в гpафическом с pазpешениями 320x200 или 640x200. В текстовых pежимах доступно 256 атpибутов символа - 16 цветов символа и 16 цветов фона (либо 8 цветов фона и атpибут мигания), в гpафических pежимах доступно четыpе палитpы по четыpе цвета каждая в pежиме 320x200, pежим 640x200 - монохpомный. Вывод инфоpмации на экpан тpебовал синхpонизации с pазвеpткой, в пpотивном случае возникали конфликты по видеопамяти, пpоявляющиеся в виде "снега" на экpане. Частота стpочной pазвеpтки - 15 кГц. Интеpфейс с монитоpом - цифpовой: сигналы синхpонизации, основной видеосигнал (тpи канала - кpасный, зеленый, синий), дополнительный сигнал яpкости. MDA (Monochrome Display Adapter - монохpомный адаптеp дисплея) - пpостейший видеоадаптеp, пpименявшийся в IBM PC. Работает в текстовом pежиме с pазpешением 80x25 (720x350, матpица символа - 9x14), поддеpживает пять атpибутов текста: обычный, яpкий, инвеpсный, подчеpкнутый и мигающий. Частота стpочной pазвеpтки - 15 кГц. Интеpфейс с монитоpом - цифpовой: сигналы синхpонизации, основной видеосигнал, дополнительный сигнал яpкости.

Работа с клавиатурой. UKBRD.C/H. 1) <STDIO.H> getchar (); fflush (stdin); 2) <CONIO.H> getch(); 3) <BIOS.H> int bioskey (int cmd); 1. при входе с cmd=0 ожидает нажатие клавиши если буфер клавиатурф пуст (емкость-до 16 кодов). При непустом буфере извлекает из него очередной код. 1) мл байт !=0-ASCKI-код клавиши => старший байт содержит SCANCODE нажатой клавиши. 2) мл байт=0 (спец клавиши: |, ->, F1..F10) и старший байт содержит расширенный код клавиши. 2. при cmd=1-возвращ 0 если нажатия не было, если было, то !=0; сам код клавиши должен быть считан вызовом BIOS Key (0); пробел= “_”=0x20=32; /* файл UKBRD.C */ #include <BIOS.H> #include ‘’UKBRD’’ void KbFlush (void) опорожняет буфер клав { while bioskey(1) bioskey (0); /* пока буфер не пуст извлекать из него символы */ }. Int KbHit (void) – функция проверки нажатия { if (bioskey (1)} возвращ 0-не было нажатия. Иначе возвращ код нажатой клавиши. Return bioskey (0); return 0; } функция ожидания: int KbWaitKey (void) ожидает нажатия клавиши и возвращет ее код, опорожняя буфер клавиатуры. { int key; while (! Bioskey(1)) {;} /* ожидать нажатие любой клавиши */ key=bioskey (0); /* считать код клавиши */ KbFlush (); /*затем опорожнить буфер */ return key; }

Однострочный редактор. Клавиши управления, редактирования. Обработка ошибок. Простейщий интерфейс в одной строке. 1) строка подсказки/состояния (самая нижняя строка экрана: screen tottom line-SBL). вывод/сохранение/восстановление Sbl. SblPut, SblSave, SblRestore. Реакция на ошибочную ситуацию SblWarn; двоичный запрос в Sbl- SblEscEnter; 2) выбор строки из меню; 3) однострочный редактор – StrEdit; int StrEdit (intx, inty, intendx, char str[], int attr /* атрибут окраски */) редактирует строку str с заданным attr; возвращает: НОРМА: KbENTER/KESC – ввод строки в буфере str или отказ от ввода str[]-не изменятеся. ОШИБКА: -1 – ошибка в задании координат; -2 – ошибка по y; -3 – ошибка по end x;

План функции StrSelect: 1) анализ входной информации, 2) цикл: шаг 2.1 подготовка обл экрана к показу 2.2 вывод строк меню 2.3 уст-ка формы и положения курсора 2.4 ожидание нажатия клавиш по допустимым ключам. Int StrSelect (int x, int y, /* коорд лев верх угла окна выбора */ char *menu[]. /*меню выбора */ int attr, /* атрибут при выборе */ int *choice /* на входе: индекс строки menu с которой начинается выбор */ /*на выходе: индекс выбранной строки menu */. Осуществляет показ по одной строк меню с возможн перебора вертикальными стрелками. Норма: -1 – ошибка в координатах x, y; -2 – меню содержит пустые строки (их >0); -3 – меню содержит (<2) строк; Преобразование StrSelect в StrSelect1. по ключу KbUp, KbDown. Ввести новые ключи управления Kbpgup – 1ая; Kbpgdown – послед; Kb undo – восст показа с исходной строки. 1) корректир кода в switch; 2) заполнить до основного цикла for ix0 – нач строка;

Стандартные функции установки и получения текущей позиции в графическом режиме работы экрана.

Процедуры копирования строки с ограничением длины копирования. Пример реализации.

Процедура выбора альтернативы из горизонтального меню. Клавиши управления и основные операции. Контроль ошибок и реакция на них. Пример реализации.

Процедура выбора альтернативы из вертикального меню. Клавиши управления и основные операции. Контроль ошибок и реакция на них. Пример реализации. Enum frametype. Last Frame/ Frame Space/ Frame Singal. Frame Double.

Процедуры ввода строки символов с ограничением длины. Примеры реализации.