15321

Розробка текстового редактора

Курсовая

Информатика, кибернетика и программирование

КУРСОВА РОБОТА Тема: Розробка текстового редактора/ Обєктом розробок та досліджень є текстовий редактор. Мета роботи – розробка текстового редактора. Програма була реалiзована за допомогою функцій мови Сі. В результаті роботи була розроблена програма, яка призначена для перегляду та редагування тексту. Програму виконано у середовищі Сі.

Украинкский

2013-06-11

157.5 KB

7 чел.

КУРСОВА РОБОТА

Тема: Розробка текстового редактора

РЕФЕРАТ

Пояснювальна записка до курсової роботи:

Об’єктом розробок та досліджень є текстовий редактор. Мета роботи – розробка текстового редактора.

Програма була реалiзована за допомогою функцій мови Сі.

В результаті роботи була розроблена програма, яка призначена для перегляду та редагування тексту.

Програму виконано у середовищі Сі.

 

ТЕКСТОВИЙ РЕДАКТОР, ВІДЕОПАМ’ЯТЬ, КОМАНДНИЙ РЯДОК, ЗЧИТУВАННЯ З ФАЙЛУ, ЗАПИС В ФАЙЛ

КР 7.091501-08-6559183 ПЗ

Вим

Лист

№ докум

Підп

Дата

Розр.

Розробка текстового редактора

Лит

Лист

Листів

Керів.

у

Т.контр.

ДонНТУ, кафедра КІ

Гр КС-08оз

Н.контр.

Зав.каф.

Святний В.А.

 

ДЕРЖАВНИЙ ВИЩИЙ НАВЧАЛЬНИЙ ЗАКЛАД

«ДОНЕЦЬКИЙ НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ УНІВЕРСИТЕТ»

Факультет комп”ютерних наук та технологій     Кафедра КІ

ЗАТВЕРДЖУЮ:

Зав. кафедрою КІ

___________________В.А.Святний

“.......”.................................... 2009 г.

З А В Д А Н Н Я

на курсову роботу студентцi

Шевченко Тетянi

(Ф.І.)

1. Тема роботи „Розробка текстового редактора”

2. Термін здачі студентом закінченої роботи  1 листопада 2009 р.

3. Вхідні дані до роботи

1) Програма – приклад, що переглядає текст.

2) Язик програмування С++.

3) Варіант завдання №22:

  1.  функції пересування курсора

5. Ctrl-Left – перемещение курсора на предыдущее слово текущей строки

 6. Ctrl-Right – перемещение курсора на следующее слово текущей строки

  1.  функції видалення

1. Del – Удаляет символ справа от курсора

4. Ctrl-K – Удаляет символы до конца строки

  1.  функції роботи з блоками

2. Alt-Cursor key – выделить вертикальный блок

 4. Ctrl-U – Снять выделение блока

 9. Ctrl-P – Копировать блок в текущую позицию курсора

  1.  інші функції

1. F1 – показать HELP, Esc- отмена

2. F2 – сохранить файл

3. Shift-F2 – сохранить файл под новым именем

8. Esc – выход

4. Зміст пояснювальної записки (перелік питань, що підлягають розробці)

Вступ

1) Структура та алгоритм роботи текстового редактора.

2) Розробка окремих функцій текстового редактора.

  •  зчитування вхідного тексту
  •  організація виводу на екран тексту
  •  організація функцій пересувань курсора

-     організація функцій видалення

-      організація функцій роботи з блоками

-       збереження змін у файлі

3) Аналіз результатів роботи

Висновки

Список використаної літератури

ДОДАТОК А

Текст програми текстового редактора


ЗМIСТ

[1] КУРСОВА РОБОТА

[2]
Вступ

[3]
1. Структура та алгоритм роботи текстового редактора.

[4]
2. Розробка окремих функцій текстового редактора.

[4.1] 2.1 Зчитування вхідного тексту

[4.2] 2.2 Організація виводу на екран тексту

[4.3] 2.3 Організація функцій пересувань курсора

[4.3.1] 2.3.1 Ctrl-Left – переміщення курсору на попереднє слово поточного рядка

[4.3.2] 2.3.2 Ctrl-Right – переміщення курсору на наступне слово поточного рядка

[4.4] 2.4 Організація функцій видалення

[4.4.1] 2.4.1 Del – Видаляє символ праворуч від курсору

[4.4.2] 2.4.2 Ctrl-K – Видаляє символи до кінця рядка

[4.5] 2.5 Організація функцій роботи з блоками

[4.5.1] 2.5.1 Alt-Cursor key – виділити вертикальний блок

[4.5.2] 2.5.2 Ctrl-U – Зняти виділення блоку

[4.5.3] 2.5.3 Ctrl-P – Копіювати блок у поточну позицію курсору

[4.6] 2.6 Збереження змін у файлі

[4.6.1] 2.6.1 F1 – показати HELP, Esc- скасування

[4.6.2] 2.6.2 F2 – зберегти файл

[4.6.3] 2.6.3 Shift-F2 – зберегти файл під новим іменем

[4.6.4] 2.6.4 Esc – вихід

[5]
3. Аналіз результатів роботи

[6]
Висновки

[7]
Список використаної літератури

[8] 1. Керниган Б., Ритчи Д. «Язык программирования Си»

[9] 2. Шилдт Г.  «Полный справочник по C»

[10]
ДОДАТОК А


Вступ

Даний курсовий проект присвячений вивченню принципів внутрішньої організації  операційної системи MS - DOS. MS - DOS - це перша операційна система корпорації Microsoft, яка значно розповсюдилася серед персональних комп'ютерів якийсь час тому, але її розвиток був згодом перерваний десь на початку 90-х минулого сторіччя тому, що вона мала багато недоліків - відсутність яскравого графічного інтерфейсу, однозадачність, тощо. MS-DOS змінила інша розробка Microsoft - всім відома операційна система Windows.

Вивчення MS-DOS є дуже важливим, оскільки вона є основою для Windows. ОС Windows набагато складніша ніж DOS, однак в них багато спільних принципів роботи.


1. Структура та алгоритм роботи текстового редактора.

Програма складається із трьох функцій main( ) , pr_koor( ), wr_text( ). Функція main( ) виконує читання файлу переданого у команднiй строкi, аналіз натиснутої клавіші й виклик функцій wr_text( ), pr_koor( ). Відразу після запуску функція виконує читання файлу, ім’я котрого передано через командний рядок. Після вдалого читання запускається безкінцевий цикл while(). У циклі виконується читання коду натиснутої клавіші функцією getch( ) і передача його оператору switch(). Він уже починає вибір операцій у зв'язку з кодом натиснутої клавіші.

pr_koor() виконується  вивід на екран рядка координат.

wr_text() виконує вивод змісту файлу на екран.


2. Розробка окремих функцій текстового редактора.

У цьому розділі будуть розглянуті способи реалізації окремих частин текстового редактора.

2.1 Зчитування вхідного тексту

Зчитування даних виконується за допомогою за допомогою стандартних функцій Сі. Текстовий файл передається в програму через командний рядок. Якщо змінна argc (кількість параметрів у командному рядку) менше двох, то програма завершується. Якщо було введено 2 параметра (1 - exe файл програми, 2 - текстовий файл), то програма намагається відкрити файл функцією fopen( ) у режимі читання.

 У випадку успішного відкриття файлу, виконується читання з файлу рядків довжиною 100 символів функцією fgets( ). Читання виконується в рядки матриці доти, поки не закінчиться файл, або вільні рядки матриці.

Після читання зміст файлу передається на обробку.

if(argc>=2)//Проверка на наличие параметров

  {printf("неверные параметры"); getch();goto mret;}

/*Выделение памяти под указатели*/

for(i=0;i<=100;i++)

 if((rs[i]=malloc(100))==NULL)

  {printf("Недостаточно памяти");goto mret;}

if ((f1=fopen(argv[1],"r"))==NULL)//Открытие файла

 {printf("Файл %s не открывается",argv[1]); goto mret;}

for(i=0;i<=100;i++)//Заполняем выделеную пам'ять пробелами

  for(j=0;j<=100;j++)

     *(rs[i]+j)=' ';

/*Формирование файла в памяти;*/

i=0;//Индекс строки

x1=y1=x2=y2=-1;//сброс координат блокового выделения

while(fgets(rs[i++],100,f1)!=NULL)//Цикл чтения из файла

 if(i==100) break;

kstr=i-2;

2.2 Організація виводу на екран тексту

Увесь прочитаний текст зберігається в матриці 100х100, але через обмежену область виводу дисплея, на екрані буде видна тільки область 23х80. Вибір діапазону для виводу на екран здійснюється за допомогою змінних  xt, yt, xk, yk. Де хt і yt відступ до курсору відносно початку матриці. Використовується для зміни позиції прямокутника вікна. xk та yk відповідають за переміщення каретки у вікні.

Вивід тексту здійснюється через відеобуфер, екран реалізований у функції wr_text( ). Також у цій функції реалізовано зміну кольору блокового виделення.

void wr_text(int xt,int yt,int xk,int yk)//Функция выполняет вывод текста

{

int i,j;

clrscr();//Очистка экрана

if (x1>x2){ xr=x1; xl=x2;}//Сортируем координаты выделения по х

else{ xr=x2; xl=x1;}

if (y1>y2){ yr=y1; yl=y2;} //Сортируем координаты выделения по у

else{ yr=y2; yl=y1;}

for(i=0;i<=22;i++)//Цикл вывода

  for(j=0;j<=79;j++)//текста на экран

   {

     if((xl<=(j+xt))&&(xr>=(j+xt))&&(yl<=(i+yt))&&(yr>=(i+yt)))//Проверка на принадлежность выделеной области

     {

     if((*(rs[i+yt]+j+xt)==' ') | (*(rs[i+yt]+j+xt)=='\0') | (*(rs[i+yt]+j+xt)=='\n'))

*(p+i*80+j)=0x7F20;//печать пробела

     else

*(p+i*80+j)=(0x7F00+(*(rs[i+yt]+j+xt)));//Печать символа

     }

     else

     {

     if((*(rs[i+yt]+j+xt)==' ')|(*(rs[i+yt]+j+xt)=='\0')|(*(rs[i+yt]+j+xt)=='\n'))

*(p+i*80+j)=0x0F20; //печать пробела

     else

*(p+i*80+j)=(0x0F00+(*(rs[i+yt]+j+xt))); //Печать символа

     }

   }

pr_koor(xt,yt,xk,yk);//Вызов функции печати координат

}

2.3 Організація функцій пересувань курсора

Далі представлені алгоритми реалізації заданих по варіанту функцій пересування каретки.

2.3.1 Ctrl-Left – переміщення курсору на попереднє слово поточного рядка

При вступі цієї комбінації на обробку виконується пропуск усіх пробілів, після чого пропускаються всі символи до пробілу, або до початку рядка. У результаті курсор попадає на початок слова ліворуч від курсора.

case 115:        /*Ctrl+'Стрелка влево'*/

     {

       i=xk+xt-2;//начинаем поиск с символа слева от курсора

while((*(rs[yt+yk-1]+i)==' ')|(*(rs[yt+yk-1]+i)=='\n')|(*(rs[yt+yk-1]+i)=='\0'))i--;//Двигаемся влево, пока встречаются пробелы

while((*(rs[yt+yk-1]+i)!=' ')&&(*(rs[yt+yk-1]+i)!='\n')&&(*(rs[yt+yk-1]+i)!='\0')&&(i>0))

         i--;//Двигаемся влево, пока встричаются символы

       if (i<=0)//если вышли на начало строки

       {

         if(*(rs[yt+yk-1])!=' ')//Если первый символ строки пробел

    i=0;//переводим на него курср

         else //иначе завершаем обработку

           break;

       }

       if((i>xt)&&(i<=xt+80))//Если остановились в пределах видимой области

       {

         xk=i-xt+2;//перемещаем курсор

}

еlse//иначе

       {

    {

      xt=i;//передвигаем окно

      xk=1;//и курсор

    }

       }

       wr_text(xt,yt,xk,yk);//перерисовка текста

       break;

     }       

2.3.2 Ctrl-Right – переміщення курсору на наступне слово поточного рядка

Ця комбінація виконує дії аналогічно попереднії, тільки виконується пошук кінця слова праворуч від курсора.

     case 116:        /*Ctrl+'Стрелка вправо'*/

     {

       i=xk+xt+1;//ведем поиск с элемента справа от курсора

       while((*(rs[yt+yk-1]+i)==' ')|(*(rs[yt+yk-1]+i)=='\n')|(*(rs[yt+yk-1]+i)=='\0'))i++;//пропускаем все пробелы

       while((*(rs[yt+yk-1]+i)!=' ')&&(*(rs[yt+yk-1]+i)!='\n')&&(*(rs[yt+yk-1]+i)!='\0')&&(i<100))//пропускаем все символы

  i++;

if (i>=100)//если достигли конца строки

       {

         if(*(rs[yt+yk-1]+99)!='\0')

           i=100;//переносим курсор в конец строки

         else

    break;

       }

       if((i>xt)&&(i<xt+80))//если находимся в пределах видимой области

       {

         xk=i-xt;//переставляем курсор

       }

       else// иначе

{

  if (i>(xt+80))//если вышли за пределы видимой области

         {

    xt=i-80;//перемещаем окно

    xk=80;//ставим курсор в конец окна

         }

}

       wr_text(xt,yt,xk,yk);//перерисовка текста

       break;

     }       

2.4 Організація функцій видалення

Приведемо опис виконання функцій видалення.

2.4.1 Del – Видаляє символ праворуч від курсору

При вступі в оброблювач коду клавіші Del виконується зрушення елементів рядка праворуч від курсору на 1 позицію вліво. В останній елемент записуємо 0.

     case 83:       /*Del*/

     {

for (i=xt+xk-1;i<100;i++)//цикл с текущей позиции до конца строки

  *(rs[yt+yk-1]+i)=*(rs[yt+yk-1]+i+1);//в тек. Символ зап. следующий

*(rs[yt+yk-1]+i)='\0';//в последний записываем 0

wr_text(xt,yt,xk,yk);//Перерисовка текста

break;

     }

2.4.2 Ctrl-K – Видаляє символи до кінця рядка

З появою цієї комбінації поточний елемент і всі елементи праворуч від курсору заповнюються кодом 0

     case 11:       /*Ctrl-K*/

     {

for (i=xt+xk-1;i<100;i++)//цикл с текущей позиции курсора до конца строки

  *(rs[yt+yk-1]+i)='\0';//заполнение элементов нулем

wr_text(xt,yt,xk,yk);//перерисовка текста

break;

     }

2.5 Організація функцій роботи з блоками 

2.5.1 Alt-Cursor key – виділити вертикальний блок

При натисканні комбінації Alt і клавіша стрілки виконується взвод прапора натискання Alt в 1 і запам'ятовування координат початку виділення й координати поточної позиції курсору. У всім іншому обробка аналогічна пересуванням курсору.

     case 152:            /*Alt+'Стрелка вверх'*/

     {

 if(Alt==0)//Если блок еще не выделялся

 {

  Alt=1;//Взводим флаг блокового выделения

 }

if( yk>1)//если курсор не на верхней строке

{

  yk--;передвигаем курсор вверх

  gotoxy(xk,yk);//перерисовываем курсор

}

else//иначе

 if(yt>0)//если окно не в верху матрицы

 {

   yt--;//перемещаем окно вверх

 }

if(y1==-1)//если координата начала выделения строки не задана

  y1=yt+yk;//определяем координату начала выделения строки

y2=yt+yk-1;//определяем координату конца выделения строки

if(x1==-1)// если координата начала выделения столбца не задана

  x1=x2=xt+xk-1;// определяем координаты выделения столбца

wr_text(xt,yt,xk,yk);//перерисовка текста

break;

     }

     case 160:          /*Alt+'Стрелка вниз'*/

     {

 if(Alt==0)//Если блок еще не выделялся

 {

  Alt=1;//Взводим флаг блокового выделения

 }

if( yk<=22)//Если курсор не в последней строке

{

  yk++;//передвигаем его вниз

  gotoxy(xk,yk);//перерисовываем курсор

}

Else//иначе

  if(yt<77)//если окно не в низу матрицы

  {

    yt++;//перемещаем окно

  }

if(y1==-1)//если координата начала выделения строки не задана

  y1=yt+yk-2;//определяем координату начала выделения строки

y2=yt+yk-1;//определяем координату конца выделения строки

if(x1==-1)// если координата начала выделения столбца не задана

  x1=x2=xt+xk-1;// определяем координаты выделения столбца

wr_text(xt,yt,xk,yk);//перерисовка текста

break;

     }

     case 155:        /*Alt+'Стрелка влево'*/

     {

 if(Alt==0)//Если блок еще не выделялся

 {

  Alt=1;//Взводим флаг блокового выделения

 }

if( xk>1)//если курсор не в начале строки

{

  xk--;//передвигаем курсор влево

  gotoxy(xk,yk);//перерисовываем курсор

}

else

  if(xt>0)//если окно находится не в начале матрицы

  {

    xt--;//перемещение окна влево

  }

if(x1==-1)// если координата начала выделения столбца не задана

  x1=xk+xt;// определяем координаты начала выделения столбца

x2=xk+xt-1; // определяем координаты конца выделения столбца

if(y1==-1) //если координата начала выделения строки не задана

  y1=y2=yt+yk-1; //если определяем координаты конца выделения строки

wr_text(xt,yt,xk,yk);// перерисовка текста

break;

     }

     case 157:        /*Alt+'Стрелка вправо'*/

     {

 if(Alt==0)//Если блок еще не выделялся

 {

  Alt=1;//Взводим флаг блокового выделения

 }

if( xk<80)//если курсор не в конце строки

{

  xk++;//передвигаем курсор вправо

  gotoxy(xk,yk);//перерисовываем курсор

}

else//иначе

  if(xt<20)//если окно не сдвинуто до концаматрицы вправо

  {

    xt++;//передвигаем окно

  }

if(x1==-1)// если координата начала выделения столбца не задана

  x1=xk+xt-2;// определяем координаты начала выделения столбца

x2=xk+xt-1; // определяем координаты конца выделения столбца

if(y1==-1) //если координата начала выделения строки не задана

  y1=y2=yt+yk-1; //если определяем координаты конца выделения строки

wr_text(xt,yt,xk,yk);// перерисовка текста

break;

     }

2.5.2 Ctrl-U – Зняти виділення блоку

З появою Ctrl+U виконується скидання прапора Alt в 0 і скидання координат виділення в -1.

     case 21: /*Ctrl+U*/

     {

x1=y1=x2=y2=-1;Alt=0;//Сброс координат и флага

wr_text(xt,yt,xk,yk);//перерисовка текста

      break;

     }

2.5.3 Ctrl-P – Копіювати блок у поточну позицію курсору

З появою Ctrl-P перевіряється наявність блокового виділення. Якщо прапор Alt рівний 1, то виконується зрушення символів в область вставки блоку й копіювання блоку в цю поле, що звільнилося.

    case 16:          /*Ctrl+P*/

    {

     if(Alt)//если было блоковое выделение

     {

if (x1>x2){ xr=x1; xl=x2;}//Сортируем координаты выделения по х

  else{ xr=x2; xl=x1;}

  if (y1>y2){ yr=y1; yl=y2;} //Сортируем координаты выделения по у

  else{ yr=y2; yl=y1;}

 for (i=0;i<=(yr-yl);i++)//Цикл по строкам сверху вниз

   for(j=99;j>xr;j--)//цикл по столбцам справо до выделения

   {

     *(rs[yt+yk-1+i]+j)=*(rs[yt+yk-1+i]+j-(xr-xl));//Перенос символов вправо на ширину выдиления

   }

 for (i=yr-yl;i>=0;i--)//цикл по строкам снизу вверх

   for(j=xr-xl;j>=0;j--)//Цикл по столбцам справа влево

   {

     *(rs[yt+yk-1+i]+xk+xt-1+j)=*(rs[yl+i]+xl+j);//копирование символов из выделеной области в освободившуюся

   }

x1=y1=x2=y2=-1;Alt=0;//сброс выделения

wr_text(xt,yt,xk,yk);//перерисовка текста

      }

break;

2.6 Збереження змін у файлі

2.6.1 F1 – показати HELP, Esc- скасування

При натисканні F1 виконується очищення дисплея й вивід на екран умісту довідки. Запускається цикл очікування клавіші Escape. Після натискання на Escape виконується повернення в редактор.

     case 59:       /*F1*/

     {

       clrscr();//Очистка экрана

printf("Вариант 22. \n   1.  Функции перемещения курсора\n5. Ctrl-Left - перемещение курсора на предыдущее слово текущей строки \n6. Ctrl - Right - перемещение курсора на следующее слово текущей строки \n\n                        2. Функции удаления\n1. Del - Удаляет символ справа от курсора\n4. Ctrl-K - Удаляет символы до конца строки\n\n                            3. Функции работы с блоками\n2. Alt-Cursor key - выделить вертикальный блок\n4. Ctrl-U - Снять выделение блока\n 9. Ctrl-P - Копировать блок в текущую позицию курсора\n\n                              4. Другие операции\n1. F1 - показать HELP, Esc- отмена\n2. F2 - сохранить файл\n3. Shift-F2 - сохранить файл под новым именем\n8. Esc - выход");

       while (getch()!=27);//Ожидание нажатия Esc.

       wr_text(xt,yt,xk,yk);//перерисовка текста

break;

     }

2.6.2 F2 – зберегти файл

Клавіша F2 формує коди 0, 60. При вступі 60 видаляється вихідний файл функцією remove() і створюється новий з таким же іменем у режимі запису. Після відкриття файлу запускається цикл по рядках, що виконує печатку вмісту матриці у файл функцією fputs().

     case 60: /*F2*/

     {

remove(argv[1]);// Удаление исходного файла

f1=fopen(argv[1],"w");// Открытие файла в режиме чтения

for (i=0;i<100;i++)//Цикл записи текстовой маткицы в файл

  fputs(rs[i],f1);

fclose(f1);//Закрытие файла

break;

     }

2.6.3 Shift-F2 – зберегти файл під новим іменем

При надходженні  Shift+F2 виконується запит імені файлу для збереження й процедура збереження, аналогічна процедурі при F2

     case 85: /*Shift-F2*/

     {

      clrscr();//Очистка экрана

      printf("Имя файла: ");//вывод строки

      scanf("%s",&file);//Чтение введенной строки

      remove(file);//Удаление файла, если такой есть

      f1=fopen(file,"w");//Открытие файла в режиме чтения

 for (i=0;i<100;i++)//Цикл записи текстовой маткицы в файл

   fputs(rs[i],f1);

 fclose(f1);//Закрытие файла

      wr_text(xt,yt,xk,yk);//перерисовка текста

      break;

     }

2.6.4 Esc – вихід

З появою коду клавіші Esc в оброблювачі виконується стрибок з нескінченного циклу while() на кінець програми.

     case 27: goto mret;//Переход в конец программы


3. Аналіз результатів роботи

Згідно з технічним завданням були виконані наступні функції:

Ctrl-Left – переміщення курсору на попереднє слово поточного рядка

Ctrl-Right – переміщення курсору на наступне слово поточного рядка

Del – Видаляє символ праворуч від курсору

Ctrl-K – Видаляє символи до кінця рядка

Alt-Cursor key – виділити вертикальний блок

Ctrl-U – Зняти виділення блоку

Ctrl-P – Копіювати блок у поточну позицію курсору

F1 – показати HELP, Esc- скасування

F2 – зберегти файл

Shift-F2 – зберегти файл під новим іменем

Esc – вихід

Функції були реалізовані аналогічно функція програми FAR, працюють правильно й у результаті перевірок помилки не виявлені.


Висновки

     Результатом  курсового проекту є текстовий редактор. У програмі були виконані наступні функції:

Ctrl-Left – переміщення курсору на попереднє слово поточного рядка

Ctrl-Right – переміщення курсору на наступне слово поточного рядка

Del – Видаляє символ праворуч від курсору

Ctrl-K – Видаляє символи до кінця рядка

Alt-Cursor key – виділити вертикальний блок

Ctrl-U – Зняти виділення блоку

Ctrl-P – Копіювати блок у поточну позицію курсору

F1 – показати HELP, Esc- скасування

F2 – зберегти файл

Shift-F2 – зберегти файл під новим іменем

Esc – вихід

 Завдяки проведеній роботі були засвоїни та практично проработані навичкі по написанню програмного забеспечення.


Список використаної літератури

1. Керниган Б., Ритчи Д. «Язык программирования Си»

2. Шилдт Г.  «Полный справочник по C»


ДОДАТОК А

Текст програми текстового редактора

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <alloc.h>

#include <conio.h>

#include <dos.h>

unsigned char *rs[100];

unsigned int far *p=(unsigned int far *)MK_FP(0xB800,0x0000);

int x1,y1,x2,y2,Alt=0,xl,yl,xr,yr;

void wr_text(int xt,int yt,int xk,int yk);

void pr_koor(int xt,int yt,int xk,int yk);

void main(int argc,char *argv[])

{FILE *f1;

int i,j,c,yk,xk,xt,yt,kstr;

 int nsp;

 char file[20];

clrscr();

if(argc!=2)

  {printf("неверные параметры"); getch();goto mret;}

/*Выделение памяти под указатели*/

for(i=0;i<=100;i++)

 if((rs[i]=malloc(100))==NULL)

  {printf("Недостаточно памяти");goto mret;}

if ((f1=fopen(argv[1],"r"))==NULL)

 {printf("Файл %s не открывается",argv[1]); goto mret;}

for(i=0;i<=100;i++)

  for(j=0;j<=100;j++)

     *(rs[i]+j)=' ';

/*Формирование файла в памяти;*/

i=0;

x1=y1=x2=y2=-1;

while(fgets(rs[i++],100,f1)!=NULL)

 if(i==100) break;

kstr=i-2;

printf("kstr=%d",i);

c=getch();

clrscr();

gotoxy(1,1);

/*Вывод sr на экран*/

xt=0;yt=0;

xk=1;yk=1;

wr_text(xt,yt,xk,yk);

gotoxy(1,1);

while(1 )

{

 c=getch();

 if(c=='\0') c=getch();

 yk=wherey();xk=wherex();

  switch(c)

    {

     case 72:{if( yk>1)/*Стрелка вверх*/

               {yk--;gotoxy(xk,yk);

               pr_koor(xt,yt,xk,yk);

 }

              else

               if(yt>0)

                {yt--;wr_text(xt,yt,xk,yk);

               }

 if(Alt==1)

 {x1=y1=x2=y2=-1;Alt=0;

wr_text(xt,yt,xk,yk);}

 

              break;

             }

     case 80:{if( yk<=22)          /*Стрелка вниз*/

               {yk++;gotoxy(xk,yk);

               pr_koor(xt,yt,xk,yk);

               }

              else

               if(yt<77)

                {yt++;wr_text(xt,yt,xk,yk);

                }

 if(Alt==1)

 {x1=y1=x2=y2=-1;Alt=0;

wr_text(xt,yt,xk,yk);}       break;

             }

      case 75:{if( xk>1)        /*Стрелка влево*/

               {xk--;gotoxy(xk,yk);

                pr_koor(xt,yt,xk,yk);

               }

              else

 if(xt>0)

                {xt--;wr_text(xt,yt,xk,yk);

 }

               if(Alt==1)

 {x1=y1=x2=y2=-1;Alt=0;

 wr_text(xt,yt,xk,yk);}

  

              break;

             }

      case 77:{if( xk<80)        /*Стрелка вправо*/

               {xk++;gotoxy(xk,yk);

                pr_koor(xt,yt,xk,yk);

               }

               else

                if(xt<20)

   {

                  xt++;wr_text(xt,yt,xk,yk);

                }if(Alt==1)

 {x1=y1=x2=y2=-1;Alt=0;

wr_text(xt,yt,xk,yk);}

               break;

              }

     case 27: goto mret;

     case 116:        /*Ctrl+'Стрелка вправо'*/

     {

       i=xk+xt+1;

       while((*(rs[yt+yk-1]+i)==' ')|(*(rs[yt+yk-1]+i)=='\n')|(*(rs[yt+yk-1]+i)=='\0'))i++;

       while((*(rs[yt+yk-1]+i)!=' ')&&(*(rs[yt+yk-1]+i)!='\n')&&(*(rs[yt+yk-1]+i)!='\0')&&(i<100))

  i++;

if (i>=100)

       {

         if(*(rs[yt+yk-1]+99)!='\0')

           i=100;

         else

    break;

       }

       if((i>xt)&&(i<xt+80))

       {

         xk=i-xt;

       }

       else

{

  if (i>(xt+80))

         {

    xt=i-80;

    xk=80;

         }

}

       wr_text(xt,yt,xk,yk);

       break;

     }       

     case 115:        /*Ctrl+'Стрелка влево'*/

     {

       i=xk+xt-2;

while((*(rs[yt+yk-1]+i)==' ')|(*(rs[yt+yk-1]+i)=='\n')|(*(rs[yt+yk-1]+i)=='\0'))i--;

while((*(rs[yt+yk-1]+i)!=' ')&&(*(rs[yt+yk-1]+i)!='\n')&&(*(rs[yt+yk-1]+i)!='\0')&&(i>0))

         i--;

       if (i<=0)

       {

         if(*(rs[yt+yk-1])!=' ')

    i=0;

         else

           break;

       }

       if((i>xt)&&(i<=xt+80))

       {

         xk=i-xt+2;

}

else

       {

    {

      xt=i;

      xk=1;

    }

       }

       wr_text(xt,yt,xk,yk);

       break;

     }       

     case 83:       /*Del*/

     {

for (i=xt+xk-1;i<100;i++)

  *(rs[yt+yk-1]+i)=*(rs[yt+yk-1]+i+1);

*(rs[yt+yk-1]+i)='\0';

wr_text(xt,yt,xk,yk);

break;

     }

     case 11:       /*Ctrl-K*/

     {

*(rs[yt+yk-1]+(xt+xk-1))='\0';

for (i=xt+xk;i<100;i++)

  *(rs[yt+yk-1]+i)='\0';

wr_text(xt,yt,xk,yk);

break;

     }

     case 152:            /*Alt+'Стрелка вверх'*/

     {

 if(Alt==0)

 {

  Alt=1;

 }

if( yk>1)

{

  yk--;

  gotoxy(xk,yk);

}

else

 if(yt>0)

 {

   yt--;

 }

if(y1==-1)

  y1=yt+yk;

y2=yt+yk-1;

if(x1==-1)

  x1=x2=xt+xk-1;

wr_text(xt,yt,xk,yk);

break;

     }

     case 160:          /*Alt+'Стрелка вниз'*/

     {

 if(Alt==0)

 {

  Alt=1;

 }

if( yk<=22)

{

  yk++;

  gotoxy(xk,yk);

}

else

  if(yt<77)

  {

    yt++;

  }

if(y1==-1)

  y1=yt+yk-2;

y2=yt+yk-1;

if(x1==-1)

  x1=x2=xt+xk-1;

wr_text(xt,yt,xk,yk);

break;

     }

     case 155:        /*Alt+'Стрелка влево'*/

     {

 if(Alt==0)

 {

  Alt=1;

 }

if( xk>1)

{

  xk--;

  gotoxy(xk,yk);

}

else

  if(xt>0)

  {

    xt--;

  }

if(x1==-1)

  x1=xk+xt;

x2=xk+xt-1;

if(y1==-1)

  y1=y2=yt+yk-1;

wr_text(xt,yt,xk,yk);

break;

     }

     case 157:        /*Alt+'Стрелка вправо'*/

     {

 if(Alt==0)

 {

  Alt=1;

 }

if( xk<80)

{

  xk++;

  gotoxy(xk,yk);

}

else

  if(xt<20)

  {

    xt++;

  }

if(x1==-1)

  x1=xk+xt-2;

x2=xk+xt-1;

if(y1==-1)

  y1=y2=yt+yk-1;

wr_text(xt,yt,xk,yk);

break;

     }

     case 21: /*Ctrl+U*/

     {

x1=y1=x2=y2=-1;Alt=0;

wr_text(xt,yt,xk,yk);

      break;

     }

    case 16:          /*Ctrl+P*/

    {

     if(Alt)

     {

 if (x1>x2)

 { xr=x1; xl=x2;}

 else

 { xr=x2; xl=x1;}

 if (y1>y2)

 { yr=y1; yl=y2;}

 else

 { yr=y2; yl=y1;}

 for (i=0;i<=(yr-yl);i++)

   for(j=99;j>xr;j--)

   {

     *(rs[yt+yk-1+i]+j)=*(rs[yt+yk-1+i]+j-(xr-xl));

   }

 for (i=yr-yl;i>=0;i--)

   for(j=xr-xl;j>=0;j--)

   {

     *(rs[yt+yk-1+i]+xk+xt-1+j)=*(rs[yl+i]+xl+j);

   }

x1=y1=x2=y2=-1;Alt=0;

wr_text(xt,yt,xk,yk);

      }

break;

     }

     case 59:       /*F1*/

     {

       clrscr();

printf("Вариант 22. \n   1.  Функции перемещения курсора\n5. Ctrl-Left - перемещение курсора на предыдущее слово текущей строки \n6. Ctrl - Right - перемещение курсора на следующее слово текущей строки \n\n                        2. Функции удаления\n1. Del - Удаляет символ справа от курсора\n4. Ctrl-K - Удаляет символы до конца строки\n\n                            3. Функции работы с блоками\n2. Alt-Cursor key - выделить вертикальный блок\n4. Ctrl-U - Снять выделение блока\n 9. Ctrl-P - Копировать блок в текущую позицию курсора\n\n                              4. Другие операции\n1. F1 - показать HELP, Esc- отмена\n2. F2 - сохранить файл\n3. Shift-F2 - сохранить файл под новым именем\n8. Esc - выход");

       while (getch()!=27);

       wr_text(xt,yt,xk,yk);

break;

     }

     case 60: /*F2*/

     {

      remove(argv[1]);

      f1=fopen(argv[1],"w");

      for (i=0;i<100;i++)

      {

        fputs(rs[i],f1);

      }

      fclose(f1);

      break;

     }

     case 85: /*Shift-F2*/

     {

      clrscr();

      printf("Имя файла: ");

      scanf("%s",&file);

      remove(file);

      f1=fopen(file,"w");

      for (i=0;i<100;i++)

      {

 fputs(rs[i],f1);

      }

      fclose(f1);

      wr_text(xt,yt,xk,yk);

      break;

     }

    }

 }

mret:;

}

void wr_text(int xt,int yt,int xk,int yk)

{

int i,j;

clrscr();

if (x1>x2){ xr=x1; xl=x2;}

else{ xr=x2; xl=x1;}

if (y1>y2){ yr=y1; yl=y2;}

else{ yr=y2; yl=y1;}

for(i=0;i<=22;i++)

  for(j=0;j<=79;j++)

   {

     if((xl<=(j+xt))&&(xr>=(j+xt))&&(yl<=(i+yt))&&(yr>=(i+yt)))

     {

     if((*(rs[i+yt]+j+xt)==' ')|(*(rs[i+yt]+j+xt)=='\0')|(*(rs[i+yt]+j+xt)=='\n'))

*(p+i*80+j)=0x7F20;

     else

*(p+i*80+j)=(0x7F00+(*(rs[i+yt]+j+xt)));

     }

     else

     {

     if((*(rs[i+yt]+j+xt)==' ')|(*(rs[i+yt]+j+xt)=='\0')|(*(rs[i+yt]+j+xt)=='\n'))

*(p+i*80+j)=0x0F20;

     else

*(p+i*80+j)=(0x0F00+(*(rs[i+yt]+j+xt)));

     }

   }

pr_koor(xt,yt,xk,yk);

}

void pr_koor(int xt,int yt,int xk,int yk)

{

gotoxy(35,25);

printf("line %2d,pos %2d (xk=%2d,yk=%2d,xt=%2d,yt=%2d)",yk+yt,xk+xt,xk,yk,xt,yt);

gotoxy(xk,yk);

}