Форум русскоязычного сообщества Ubuntu


Следите за новостями русскоязычного сообщества Ubuntu в Twitter-ленте @ubuntu_ru_loco

Автор Тема: Простой консольный текстовый редактор на C  (Прочитано 14157 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн inkblack

  • Старожил
  • *
  • Сообщений: 1216
    • Просмотр профиля
Re: Простой консольный текстовый редактор на C++
« Ответ #30 : 27 Апреля 2013, 01:17:10 »
Ну, если заработало, не буду разбираться, что там надо на Live системе делать.
Работает — и OK.

...
Некоторые моменты:
1. По Ctrl+C не убивается;
2. По F10 у меня выбирается пункт главного меню терминала File;
3. Нету Backspace, Enter, Delete
4. Не читает file.txt если ./editorr file.txt

А вообще класно!
...

1. И не должно. Для этого я и вызываю функцию raw(); сразу после initscr();
2. С F10 просто: надо в программе KEY_F(10) поменять на что-нибудь другое,
   например, KEY_F(9). Я-то у себя F10 в терминале отключил...
3. Backspace, Enter, Delete — относительно сложные в реализации, просто не успел пока.
4. Не читает, я этого тоже пока не делал. Ну, вроде чтение файла кажется
   весьма простым (хотя это совсем не так), а вот редактирование — это да...


Вообще там в исходнике я постарался дать максимально подробные комментарии.

Попробую сейчас еще добавить Delete. Не попробую, сплю уже, во сне кодить не могу :(

А пока выложу очередной вариант: добавлена кнопка home end и убрано кое-что по мелочи.

(Нажмите, чтобы показать/скрыть)

Пользователь решил продолжить мысль 27 Апреля 2013, 01:23:51:
Еще надо запретить курсору опускатся на последнюю строку + 1

Код: (C) [Выделить]
if (c_row < UL_ROW+V_ROWS) break;Так?

Вроде нет, по-моему c этими делами там всё OK.
c_row как раз всегда должен быть меньше UL_ROW+V_ROWS.
Смотрите сами: например, UL_ROW = 0, V_ROWS = 24
UL_ROW+V_ROWS получается 24. При этом c_row _всегда_! меньше 24 (от 0 до 23).

И в пункте 3 как раз и обеспечивается то, что курсор не опускается:
Цитировать
   3. А если в самой нижней строке окна, то он должен физически остаться
      на том же месте
, а файл надо подвинуть на строчку вверх:
      o_vert++;
« Последнее редактирование: 27 Апреля 2013, 08:22:07 от inkblack »
Делюсь знаниями, но их у меня мало!

Оффлайн Самір Гасимов

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
    • Просмотр профиля
Re: Простой консольный текстовый редактор на C++
« Ответ #31 : 27 Апреля 2013, 01:53:54 »
Вот же:
(Нажмите, чтобы показать/скрыть)
win 7 pro ukr @ desktop (ASUS P5L-VM 1394, Intel Pentium D 3.00GHz, 2GB DDR2, SATA WD500GB, ASUS nVidia GeForce 210 Silent 1GB DDR3)

Оффлайн inkblack

  • Старожил
  • *
  • Сообщений: 1216
    • Просмотр профиля
Re: Простой консольный текстовый редактор на C++
« Ответ #32 : 27 Апреля 2013, 02:08:01 »
Не, там всё правильно, просто в файле изначально строк, сколько указано в программе,
в последнем варианте это
Код: (c) [Выделить]
#define MAX_ROWS 30В пятой строке курсор может находиться, а ниже 30-й не уйдёт.

Смотрите, в строке статуса, в правом верхнем углу написано: L5    C8
L может увеличиться до 30, но не больше в нашем варианте.

Другое дело, что при обработке стрелок вверх/вниз надо следить, чтоб курсор не оказался
правее конца строки. Пожалуй, сначала это надо сделать, а потом Delete. Потому что Delete
не работает и это видно, а на вашем скрине может так получиться, что вы введете символы,
на экране они будут, а в файле — нет.

Сделаю сначала стрелки.
Делюсь знаниями, но их у меня мало!

Оффлайн Самір Гасимов

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
    • Просмотр профиля
Re: Простой консольный текстовый редактор на C++
« Ответ #33 : 27 Апреля 2013, 02:10:22 »
Не, там всё правильно, просто в файле изначально строк, сколько указано в программе,

Забыл про это.

А может таки не кодить во сне?
Спать пора.
win 7 pro ukr @ desktop (ASUS P5L-VM 1394, Intel Pentium D 3.00GHz, 2GB DDR2, SATA WD500GB, ASUS nVidia GeForce 210 Silent 1GB DDR3)

Оффлайн inkblack

  • Старожил
  • *
  • Сообщений: 1216
    • Просмотр профиля
Re: Простой консольный текстовый редактор на C++
« Ответ #34 : 27 Апреля 2013, 13:39:22 »
Сп. н.

Стрелки завтра, конечно.

Вот и настало завтра.

Выкладываю новую версию, там несколько переработано горизонтальное позиционирование.
Всё вынесено в отдельную функцию, которая вызывается при любом перемещении курсора.

Исходник:
(Нажмите, чтобы показать/скрыть)

Чуть позже выложу объяснение, что это за чудо-функция movecuro.


Пользователь решил продолжить мысль 27 Апреля 2013, 18:27:28:
Вот функция movecuro (move cursor & set offset):

Код: (C) [Выделить]
void movecuro(int* c_col, int* o_horz, int* f_symb, int length) {
 int delta;
 if (*f_symb > length+1) *f_symb = length+1;

 *c_col = *f_symb - 1 + UL_COL - *o_horz;
 delta  = *c_col  - UL_COL;
 if (delta < 0) { *c_col -= delta; *o_horz += delta; return; }
 if (delta >= V_COLS) { *c_col = UL_COL+V_COLS-1; *o_horz = *f_symb-V_COLS; }
}

Просто приведу пример ее работы. Предположим:
Код: (c) [Выделить]
UL_COL = 3;
V_COLS = 11;
o_horz = 6;
f_symb = 12;
c_col  = 8;
А.
 Файл такой:
    123456789-123456789-1234\n    24 симв.
    123456789-12345\n             15 симв.
    12\n                           2 симв.

 Б.
    12345678901234567890123456     — колонки в файле.
       .................
    123...789-1234567...1234      24 симв. | строки в файле.
    123...789-12345  ...          15 симв. | курсор в 12 позиции.
    12 ...           ...           2 симв. | эта строка вообще не видна.
       ...           ...
       ...           ...
       ...           ...
       .................
                 1         2
       01234567890123456789012     — колонки на экране.
 В.
        12345678901234567890123456 — колонки в файле.
       .................
       ...3456789-123...789-1234  24 симв. | строки в файле.
       ...3456789-123...          15 симв. |
       ..._          ...           2 симв. | эта строка вообще не видна,
       ...           ...                     курсор в 3 позиции.
       ...           ...
       ...           ...
       .................


На рис. А. показан файл, в первой строке 24 символа, потом 15 и 2.

На рис. Б. показано, как это может выглядеть в редакторе.
Синим выделено то, что нам реально видно в этот момент. Курсор находится во 2-й строке,
12 колонке.

Если мы нажмем стрелку вниз, должно получиться то, что на рис. В.

Что происходит, когда мы нажимаем стрелку вниз?
f_line становится равным 3.
Вызывается функция movecuro. Ей передаются:
c_col  = 8 (да, позиция курсора на экране равна именно 8)
o_horz = 6
f_symb = 12
length = 2 (да, длина третьей строки, той, на которую перешли)

Курсор был в 12 колонке файла. Но наша строка короче, поэтому
курсор переходит в максимально правую позицию, она равна 3.
Теперь смотрим, где должен оказаться курсор на экране.
В позиции UL_COL, но правее на столько, какова его позиция
в файле минус 1. И настолько левее, насколько сдвинут файл
по горизонтали (непонятно, да?) Это как раз и получается
UL_COL + (*f_symb - 1) - *o_horz. Это равно 3 + (3-1) - 6 = -1

А теперь посмотрим, на сколько отличается вычисленная позиция курсора
от самой левой колонки окна редактирования. Это delta = *c_col - UL_COL.
delta = -1 - 3. получается -4.
Если delta<0, значит, курсор оказался левее, чем ему можно находиться.
Поэтому двигаем весь файл вправо, как раз на delta, и курсор на столько же.
Получаем f_symb = 3, c_col = -1 + 4, это 3, o_horz = 6 - 4 = 2.

Итак, в разобранном случае f_symb, c_col и o_horz получили новые правильные
значения.

Теперь рассмотрим другой случай: в положении Б. нажимаем стрелку вверх.
курсор должен сдвинуться на 1 позицию вверх, f_symb, c_col и o_horz
поменяться не должны.
Смотрим:
f_line становится равным 1.
Вызывается функция movecuro. Ей передаются:
c_col  = 8
o_horz = 6
f_symb = 12
length = 24 (длина первой строки, той, на которую перешли)

Курсор был в 12 позиции, а максимально возможная — 25. Поэтому ничего
никуда не двигаем.
Теперь вычисляем c_col.
3 + (12-1) - 6 = 8.  Ну, так и было.
delta получается 8 - 3 = 5
Это больше 0, то есть курсор должен быть правее левой границы окна.
Теперь проверим, не слишком ли далеко он сдвинут вправо:
если delta равна ширине окна редактирования или больше, то слишком.
Но в нашем случае это не так. Поэтому c_col и o_horz не меняются (в последней строке функции).
Итого, в данном случае movecuro возвращает назад после проверок то, что ей передали:
c_col  = 8, o_horz = 6, f_symb = 12.

А теперь нажмем END. Позиция курсора в файле должна стать равной длине текущей строки
плюс 1. Потом вызывается movecuro с параметрами:
c_col  = 8
o_horz = 6
f_symb = 25
length = 24 (длина первой строки, той, на которую перешли)


f_symb сравниваем c length+1. Они равны.

Находим c_col: 3 + 25-1 - 6, получается 21, т. е., курсор должен оказаться в 21 колонке экрана.
Это действительно так, посмотрите на схеме. Проверяем дальше.
delta получается 21 - 3, это 18. И это больше, чем V_COLS, (=11).
Тогда выполняются действия в последней строке функции: положение курсора на экране —
правый край окна редактирования, соответственно задается и o_horz.

Пользователь решил продолжить мысль 27 Апреля 2013, 19:01:06:
Сделал Delete и Backspace, но пока немного некорректно работают.
— Всё хорошо, поправил. Но с Enter всё сложнее, сразу сейчас не сделаю.
« Последнее редактирование: 27 Апреля 2013, 19:29:02 от inkblack »
Делюсь знаниями, но их у меня мало!

Оффлайн Самір Гасимов

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
    • Просмотр профиля
Re: Простой консольный текстовый редактор на C++
« Ответ #35 : 27 Апреля 2013, 19:28:35 »
inkblack, сегодня будет боле-менее рабочий код?
Хотел бы сесть, и хорошенько проанализировать весь код. Если уж сам и не приложил усилий к написанию то хотябы основательно разобратся.
И здать уже пора бы проподавателю.
win 7 pro ukr @ desktop (ASUS P5L-VM 1394, Intel Pentium D 3.00GHz, 2GB DDR2, SATA WD500GB, ASUS nVidia GeForce 210 Silent 1GB DDR3)

Оффлайн inkblack

  • Старожил
  • *
  • Сообщений: 1216
    • Просмотр профиля
Re: Простой консольный текстовый редактор на C++
« Ответ #36 : 27 Апреля 2013, 19:54:06 »
Вот новая версия: сделаны вверх, вниз, вправо, влево, home, end.
Delete и Backspace работают, но там немного неуклюжий код.
ASCII-символы вводятся.

НЕ сделаны: Enter, чтение файла с диска, сохранение файла с именем;
пока что редактировать можно только «набор строк», их количество
заранее фиксировано, длина каждой не может превышать заранее заданного
значения. Сохраняются все строки из «набора», т. е., если их было 500,
то и в выходном файле будет 500, даже если вы ничего не меняли.

Всё сегодня не сделаю точно. Скажите, что нужнее в первую очередь?

А пока вот исходник:
(Нажмите, чтобы показать/скрыть)

Пользователь решил продолжить мысль 27 Апреля 2013, 19:57:29:
Вероятно, некоторые вещи на C++ сделать гораздо проще, чем на C,
ту же работу со строками, используя какие-то библиотеки, но Плюсы
я не знаю совсем :(

Пользователь решил продолжить мысль 27 Апреля 2013, 20:35:51:
Склоняюсь к мысли, что лучше начать с работы Enter.

Там довольно много надо добавить, но после этого вся фигня
с количеством строк будет легко устранена.

Пользователь решил продолжить мысль 27 Апреля 2013, 23:53:55:
Самір, напишите чтение строк из файла, чтобы работало

editorr our_file

и запись в файл, у меня в примере выводится в b.out.out, а вам
надо сделать, чтобы editorr записывал обратно в our_file.

Для контроля делайте что-нибудь с прочитанными строками, чтобы
можно было проверить, что они действительно прочитаны и записаны.

Я очень надеюсь, что завтра сумею добить Enter, Backspace и Del.

Тогда можно будет собрать всё воедино, и получится наконец редактор.
« Последнее редактирование: 27 Апреля 2013, 23:53:55 от inkblack »
Делюсь знаниями, но их у меня мало!

Оффлайн inkblack

  • Старожил
  • *
  • Сообщений: 1216
    • Просмотр профиля
Re: Простой консольный текстовый редактор на C++
« Ответ #37 : 29 Апреля 2013, 00:30:02 »
Самір, практически всё готово, с утра будет код. Сейчас не смогу,
малость приболел.
Делюсь знаниями, но их у меня мало!

Оффлайн inkblack

  • Старожил
  • *
  • Сообщений: 1216
    • Просмотр профиля
Re: Простой консольный текстовый редактор на C++
« Ответ #38 : 30 Апреля 2013, 19:51:06 »
Короче, вот что пока удалось. Enter сделал, Delete — нет,
т. е., строки добавлять можно, а убивать пока нельзя.

На работе замучили, поэтому раньше никак не мог :(

Чуть позже добавлю свои комментарии по поводу того, что получилось.

А, да, там теперь 2 сорца и 1 хедер, компилим:
Код: (bash) [Выделить]
gcc -lncurses editorr.c lines.c -o editorr

Пользователь решил продолжить мысль 30 Апреля 2013, 21:04:59:
Ну и что тут можно сказать? Во-первых, прога написана на Си,
а не на Плюсах. Все эти велосипеды в lines.c для C++ не
годятся. В плюсах есть String, есть new, а не LINNE и malloc.

Всё равно как на классическом C писать что-то вроде
Код: (C) [Выделить]
if (CH == 259) goto METKA1;
if (CH == 262) goto LEIBEL851A;
goto FINISH35;
METKA1:
/* bla-bla-bla */
goto FINISH35;
LEIBEL851A:
/* bla-bla-bla */
goto FINISH35;
Скомпилится, и работать будет, но... Это не Си вовсе.

ПО-ХОРОШЕМУ, надо всю логику программы изложить с использованием
иной идеологии, идеологии Плюсов.

А во-вторых... Дело в том, что я впервые делал такую вещь. Я просто
не знал, из каких этапов состоит, к примеру, обработка кнопок в
редакторе. Пришлось разбираться буквально на ходу. На полпути
оказалось, что придется выковыривать из кода кусок, который там
приделан в 10 местах и заменять на новый. Сейчас видно, что в куче
мест выполняется куча однотипных действий. А повсеместные вызовы
get_lin()? Вообще жесть.
Короче, надо всё переписать заново, с учетом полученных знаний.

И, подводя итог: все-таки не так плоха эта прога, если посмотреть
на её аппетит. Потребление проца — меньше одного процента, это
если нажать клавишу и не отпускать. С памятью не так хорошо, поскольку
большой pad требует много памяти. Это решение забавное, но потом
от него придется отказаться.
« Последнее редактирование: 30 Апреля 2013, 21:04:59 от inkblack »
Делюсь знаниями, но их у меня мало!

Оффлайн Самір Гасимов

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
    • Просмотр профиля
inkblack, все мегакруто!
win 7 pro ukr @ desktop (ASUS P5L-VM 1394, Intel Pentium D 3.00GHz, 2GB DDR2, SATA WD500GB, ASUS nVidia GeForce 210 Silent 1GB DDR3)

Оффлайн inkblack

  • Старожил
  • *
  • Сообщений: 1216
    • Просмотр профиля
Я рад :)
Делюсь знаниями, но их у меня мало!

Lifewalker

  • Гость
В инете никак не найду исходники.
Квинтэссенция современного образования. :(

Оффлайн SergeyIT

  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 5589
  • Все по палатам!
    • Просмотр профиля
Квинтэссенция современного образования. :(
Да уж. В свое время за неделю писали редактор, причем, практически ручкой на бумаге...
Извините, я все еще учусь

Оффлайн Чистый

  • Почётный модератор
  • Старожил
  • *
  • Сообщений: 3473
  • nix - вот оно счастье...
    • Просмотр профиля
Квинтэссенция современного образования. :(
Да уж. В свое время за неделю писали редактор, причем, практически ручкой на бумаге...
и практически без библиотек и документации а главное без интернета как такового....
Тестовый репозиторий kdeNeur ppa:devcode/kdeneur
各々が死ぬことをどのように決定する

Оффлайн inkblack

  • Старожил
  • *
  • Сообщений: 1216
    • Просмотр профиля
Ну, вы обижаете.
Я за неделю и написал.
Не ручкой конечно, и с интернетом, да.

И не доделан он пока. Но и делал я в свободное от работы время.

Чистый, кстати, может тему в Программирование перенести?
Ей там самое место.
Делюсь знаниями, но их у меня мало!

 

Страница сгенерирована за 0.065 секунд. Запросов: 25.