10.2 Редактор строки
Рассмотрим программу ввода и
редактирования строки символов. На входе этой функции передаются: экранные
координаты строки и столбца, указатель на строку ввода и максимальный размер
строки. Функция организована следующим образом: организуется цикл ввода
символа. Если это управляющий символ, то производится преобразование в
соответствии с таблицей 1. Преобразование организовано следующим образом:
библиотечная функция getch() ожидает ввода очередного символа, если символ
управляющий, то эта функция первоначально возвращает ноль, а затем код нажатой
клавиши. Отсюда легко предложить следующий алгоритм нумерации управляющих
клавиш: if(!(ch=getch())) ch=getch()+CONTROL; Читать
код символа если это ноль, то читать следующий код символа и прибавить
некоторое смещение CONTROL. Ниже записана таблица определений для управляющих
клавиш и их комбинаций.
| #define
|
CONTROL
|
255
|
смещение для разграничения управляющих клавиш
|
| #define
|
KEY_LEFT
|
75+(CONTROL)
|
//стрелка влево
|
| #define
|
KEY_RIGHT
|
77+(CONTROL)
|
//стрелка вправо
|
| #define |
KEY_HOME |
71+(CONTROL) |
//код клавиши Home |
| #define |
KEY_END |
79+(CONTROL) |
//код клавиши End |
| #define |
KEY_UP
|
72+(CONTROL) |
//код клавиши Стрелка вверх
|
| #define |
KEY_DOWN |
80+(CONTROL) |
//код клавиши Стрелка вниз |
| #define |
KEY_BACKSPACE |
8 |
//код клавиши Забой |
| #define |
KEY_DEL |
83+(CONTROL) |
//код клавиши Delete |
| #define |
KEY_ENTER |
13 |
//код клавиши Ввод |
| #define |
KEY_F1 |
59+(CONTROL) |
//код клавиши F1 |
| #define |
KEY_INSERT |
82+(CONTROL) |
//код клавиши Insert |
| #define |
KEY_ESC |
27 |
//код клавиши Esc |
| #define |
KEY_CTRL_RIGHT |
116+(CONTROL) |
//код нажатия двух клавиш Ctrl и -> |
| #define |
KEY_CTRL_LEFT |
115+(CONTROL) |
//код нажатия двух клавиш Ctrl и <- |
| #define
|
KEY_CTRL_Y |
25 |
//код нажатия двух клавиш Ctrl и y |
| #define
|
KEY_TAB |
9 |
//код клавиши Tab |
Таблица 10.1: Таблица управляющих клавиш
Теперь мы имеем алгоритм
распознавания кодов управляющих клавиш и кодов символов. Ниже в таблице
перечислены основные действия, которые выполняются на нажатие управляющих
клавиш.
| KEY_LEFT |
передвинуть курсор влево |
| KEY_RIGHT |
передвинуть курсор вправо |
| KEY_HOME |
передвинуть курсор в начало |
| KEY_END |
передвинуть курсор в конец |
| KEY_UP |
вернуть |
| KEY_DOWN |
вернуть |
| KEY_BACKSPACE |
удалить предыдущий символ |
| KEY_DEL |
удалить текущий символ |
| KEY_ENTER |
Ввод строки |
| KEY_ESC |
отмена ввода, возврат |
| KEY_TAB |
вернуть |
Таблица 10.2: Oсновные действия
-
Ниже представлен исходный текст функции редактирования строки
-
int
KruEditString(int x, int
y, char *str, int
maxlen)
{
int
len=strlen(str); //вычислить размер строки
int
pos=0; //позиция курсора в начале
int
ch;
gotoxy(x,y); //переместить курсор экрана в заданную позицию
cprintf("%s",str); //вывести строку в позиции курсора
do
//цикл ввода и редактирования
{
gotoxy(x+pos,y); //установить курсор в заданную позицию
if(!(ch=getch()))
ch=getch()+CONTROL; //взять введенный код
switch(ch) //выполнить действие в зависимости от кода
{
case
KEY_ESC: return 0; //нажата ESC, вернуть 0
case KEY_ENTER: return
1; //нажата клавиша Enter
case KEY_TAB: return
2; //нажата клавиша Tab
case KEY_DOWN: return
3; //нажата клавиша Down
case KEY_UP: return
4; // нажата клавиша Up
case KEY_HOME: pos=0; break;
//курсор переместить в начала строки
case KEY_END: pos=len; break;.
// курсор переместить в конец строки
case KEY_LEFT: if(pos>0)
pos--; break; // передвинуть курсор влево
case KEY_RIGHT:if(pos<len)
pos++; break;//передвинуть курсор вправо
case KEY_DEL: //удалить символ
if(pos<len)
{
memmove(&str[pos],&str[pos+1],len-pos+1);
len--;
cprintf("%s",&str[pos]);
putch(’ ’);
}
break;
case
KEY_BACKSPACE: //удалить предыдущий символ
if(pos>0)
{
pos--;
memmove(&str[pos],&str[pos+1],len-pos+1);
len--;
gotoxy(x+pos,y);
cprintf("%s",&str[pos]);
putch(’ ’);
}
break;
default:
//ввод символа в строку
if(len<maxlen-1)
{
memmove(&str[pos+1],&str[pos],len-pos+1);
str[pos]=ch;
cprintf("%s",&str[pos++]);
len++;
}
break;
}
} while(1);
return
0;
}
Обратите внимание на библиотечную
функцию memmove, описанную в mem.h. Эта функция копирует правильно даже в тех
случаях, когда блоки источника и приемника перекрываются.При вставке эта
функция раздвигает строку в заданной позиции, при удалении сдвигает.
-
Ниже описан
пример вызова редактора строки:
-
void main()
{
char
string[40]="Hello World !!!";
KruEditString(5,5,string,40);
gotoxy(5,10);
printf("Result:
%s",string);
while(!kbhit());
}
|