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


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

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

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

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

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
    • Просмотр профиля
Учусь в университете. По програмированию задали написать простой консольный текстовый редактор на C++
В инете никак не найду исходники.
Сам уже неделю бьюсь в попытках что-то изобразить, но никак.
Может сообщесво поможет? Или тыкнет носом куда положено?


Пользователь решил продолжить мысль 23 Апрель 2013, 23:38:22:
Нужно что-то наподобии nano, но еще проще.
Чтобы открыть файл (если в качестве параметра указан путь к файлу) или создать в текущей директории, отредактировать, и сохранить.


Пользователь решил продолжить мысль 23 Апрель 2013, 23:58:02:
Некоторые отдельные части у меня получаются, а вот собрать воедино..

Так читаю содержимое файла указаного как параметр
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <windows.h>
#include <conio.h>
#include <string>

using namespace std;
int main (int argc, char *argv[])
{
    setlocale(LC_ALL, "Ukrainian"); // Коректне відображення Кирилиці

    string clipboard;                   
    ifstream argfile (argv[1]);       
    if (argfile.is_open())
    {
        while (argfile.good())
        {
            getline (argfile,clipboard);
            cout << clipboard << endl;
        }
    argfile.close();
    }
    else cout << "Unable to open file";

    system ("PAUSE");
    return 0;
}
« Последнее редактирование: 03 Май 2013, 10:45:44 от Чистый »
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
    • Просмотр профиля
С помощью curses и функции newpad совсем легко
сделать что-то типа View по F3 в Midnight Commander.
Отсюда опять же несложно перейти к примитивному редактору.

Но это если делать всё самому.

Вообще, кроме одной весьма древней книжки ничего не видел
в сети по этой теме.

Да, кстати, напишите, какие сроки и какая платформа?
Делюсь знаниями, но их у меня мало!

Оффлайн SergeyIT

  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 5033
  • Все по палатам!
    • Просмотр профиля
Извините, я все еще учусь

Оффлайн inkblack

  • Старожил
  • *
  • Сообщений: 1216
    • Просмотр профиля
Ага, платформа, вижу, Шindoшs. Там вроде curses нету.

Но всё равно, посмотрите по ссылке, идея с «виртуальным
окном» хороша, ИМХО.
Делюсь знаниями, но их у меня мало!

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

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
    • Просмотр профиля
Ага, платформа, вижу, Шindoшs. Там вроде curses нету.

Спасибо inkblack.
Тут такое.. Я сейчас в Windows. Но надо написать под Linux. Пишу в Geany, компилятор GCC
Буду смотреть в curses.

Очень хочу сам все сделать. Ну, или так, чтобы понял все этапы.

До конца этой недели желательно все сделать.

SergeyIT, сорцы ed намного лучшет того же nano, приступил к анализу.


Пользователь решил продолжить мысль 24 Апрель 2013, 00:34:11:
Только вот, там C...
« Последнее редактирование: 24 Апрель 2013, 00:34:11 от Самір Гасимов »
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
    • Просмотр профиля
Как бы я стал делать.

Сначала решим, что редактор должен вообще уметь:

А. Открыть существующий файл для чтения-записи, если файл read-write. Напимер:
   $ editorr /home/user/file.txt
Б. Открыть существующий файл только для чтения, если файл read-only. Напимер:
   $ editorr /etc/default/grub
В. Если указанного файла нет, то создать его, например:
   $ editorr new-file
Г. А если нельзя его создать, то напечатать сообщение и закончить работу:
   $ editorr /etc/default/new-grub
   Cannot create file `/etc/default/new-grub'
   Access denied.

Д. Если редактор вызван без аргументов, открыть окно редактирования с новым
   файлом без имени.
Е. Если задано больше одного аргумента, напечатать usage:
   $ editorr 1 2 3
   A simple text editor. Usage:
   editorr [FILE]

Делюсь знаниями, но их у меня мало!

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

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
    • Просмотр профиля
Сначала решим, что редактор должен вообще уметь

Все верно.
Пункт Е так осуществить?:
if (argc < 2) {
        cout << "No filename\n";
        cout << "Usage:\n";
        exit(1);
}
   
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
    • Просмотр профиля
Пункт Е надо так:

Код: C
  1. if (argc > 2) {
  2.         cout << "Too many files\n";
  3.         cout << "Usage:\n";
  4.         exit(1);
  5. }

А если (argc < 2), то надо создать пустой файл, это к пункту Д.
Делюсь знаниями, но их у меня мало!

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

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
    • Просмотр профиля
Пункт Е надо так:
Да. Голова уже слабо варит.

Пользователь решил продолжить мысль 24 Апрель 2013, 11:13:14:
Я более всего не могу понять как сделать то самое окно редактирования.
« Последнее редактирование: 24 Апрель 2013, 11:13:14 от Самір Гасимов »
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
    • Просмотр профиля
Про окно редактирования написано в этом посте ниже.
Но надо еще понять, что в этом окне делать.

А пока пойдем по порядку. Какие операции c файлом надо делать?

А. «Сохранить как». Запрашивается путь/к/файлу/имя.файла. Файл
   сохраняется c указанным именем. Если сохранить файл нельзя,
   например, он был только для чтения, выдать сообщение об
   ошибке и продолжить сеанс редактирования.

Б. «Сохранить». Записать изменения в файл под тем именем, под
   которым он был открыт или сохранен в предыдущий раз.
   Если при сохранении возникнет ошибка (например, кончилось
   место на диске), точно так же надо выдать сообщение
   и продолжить сеанс.

В. «Выход». Если файл был изменен, то спросить: «Сохранить файл?» (Да, Нет)
   Если «Нет», то закончить работу программы, ничего не сохраняя.
   Если «Да», то сохранить, и если файл сохранен успешно, то опять же
   закончить работу.

   Если же при сохранении возникла ошибка, то сообщить о ней и
   дать запрос на сохранение под другим именем. Если пользователь откажется
   сохранить под другим именем, продолжить сеанс редактирования.


Теперь. Что в окне редактирования делаем?

А. Перемещения курсора. Вправо, влево, вверх, вниз. Home, end, PgUp, PgDn.
   Разобрать особые случаи, когда курсор в самой верхней строке окна (как обработать
   вверх), в нижней строке окна — обработать вниз; еще: курсор в первой строке / в конце
   файла. Как обработать стрелку вправо, если курсор в конце строки, как обработать
   вправо / end, если конец строки за пределами окна, ну и т. п.

Б. добавление символа:

   было:  tst,  нажали  «e»,  стало:  test

   Обработка ситуации, когда получившаяся строка слишком длинная. Что это — разберем потом.

В. Добавление строки. То, что в большинстве редакторов получается, если нажать Enter.
   Обработка ситуации, когда в файле получается слишком много строк. Тоже разберем потом.

Г. Удаление символа кнопкой Del. Удаление символа кнопкой Backspace.

Д. Удаление строки кнопкой Del, это когда курсор стоит в конце строки, и после
   нажатия следующая строка присоединяется к текущей. Удаление строки кнопкой Backspace,
   когда курсор стоит в начале строки, после нажатия текущая строка присоединяется
   к предыдущей.




Собсно, получается вполне «функциональная» прога, можно пару символов поменять
в каком-нибудь конфиге.

Кстати, здесь нашел пример. Именно работа с окном, в котором строк больше, чем видно на экране.

Начинается с
Код: C
  1. #include <curses.h>
  2. #include <locale.h>
  3. // Снятие выделения с одной строки и установка на другую строку
  4. void line_select(WINDOW * pad, int sel_pos, int old_sel_pos) {
  5.         // Установка атрибутов символов в нужной строке
  6.         mvwchgat(pad, old_sel_pos, 0, 11, A_NORMAL, 0, 0);
  7.         mvwchgat(pad, sel_pos, 0, 11, A_REVERSE, 0, 0);
  8. }
  9.  

И наконец!!! Вот окно редактирования!!!

Правда, на Си, а не на Плюсах, ну уж простите, по-другому не умею.
Компилить надо так:
Код: Bash
  1. gcc -lncurses editorr.c -o editorr
Перед этим надо установить хедеры для ncurses:
Код: Bash
  1. sudo apt-get install libncurses5-dev
Исходник:
(Нажмите, чтобы показать/скрыть)
Делюсь знаниями, но их у меня мало!

Оффлайн SergeyIT

  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 5033
  • Все по палатам!
    • Просмотр профиля
Re: Простой консольный текстовый редактор на C++
« Ответ #10 : 25 Апрель 2013, 12:35:03 »
Самір Гасимов,
Во, нашел
(Нажмите, чтобы показать/скрыть)
Извините, я все еще учусь

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

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
    • Просмотр профиля
Re: Простой консольный текстовый редактор на C++
« Ответ #11 : 25 Апрель 2013, 15:19:59 »
inkblack, это я правильно понял?

Код: C
  1. /* Вправо                                                 */  
  2.   case KEY_RIGHT:
  3.    if (f_symb == MAX_COLS) break;
  4.    if (c_col < UL_COL+V_COLS-1) c_col++;
  5.     else               o_horz++;
  6.    f_symb++;
  7.    break;
  8. /* Влево                                                 */  
  9.   case KEY_LEFT:
  10.    if (f_symb == 1) break;
  11.    if (c_col > UL_COL) c_col--;
  12.     else               o_horz--;
  13.    f_symb--;
  14.    break;

Пользователь решил продолжить мысль 25 Апрель 2013, 15:37:50:
(Нажмите, чтобы показать/скрыть)

Пользователь решил продолжить мысль 25 Апрель 2013, 15:59:34:
Для HOME верно?

Код: C
  1. // Home                                                  
  2.   case KEY_HOME:
  3.    c_row  = UL_ROW;
  4.    c_col  = UL_COL;
  5.    f_line = 1;
  6.    f_symb = 1;
« Последнее редактирование: 25 Апрель 2013, 15:59:34 от Самір Гасимов »
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++
« Ответ #12 : 25 Апрель 2013, 17:50:34 »
KEY_LEFT, KEY_RIGHT —
В принципе, правильно.

Другой вопрос в том, что есть масса вариантов. Обычно в редакторах
курсору «не дают» находиться правее конца строки, как вот тут:

  Line 1\n
  \n                            _  <- курсор
  Line number three\n
  ...
 

Посмотрите, как перемещается курсор в том же gedit-е, когда в окне
по ширине умещается, например, 80 символов, и есть две строки: 150
символов, а следующая — 20. Поставьте курсор в 140-ю позицию в первой
строке и нажмите стрелку вниз. А потом — вверх. Всё это можно реализовать,
но нужно время.

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

HOME: Обычно такое делается, когда нажимают Ctrl-HOME. И надо добавить ещё
Код: C
  1. o_vert = o_horz = 0;

Фактически Ctrl-HOME сделано в самом начале программы, сразу после инициализации
curses.

А HOME в смысле «в начало строки» — это
Код: C
  1.   case KEY_HOME:
  2.    if (f_symb == 1) break;
  3.    c_col =  UL_COL;
  4.    o_horz = 0;
  5.    f_symb = 1;
  6.    break;

(Нажмите, чтобы показать/скрыть)
Делюсь знаниями, но их у меня мало!

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

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
    • Просмотр профиля
Re: Простой консольный текстовый редактор на C++
« Ответ #13 : 25 Апрель 2013, 18:04:33 »
Я думаю можно обойтись одним Home который будет вести в самое начало.
Про pads не понял.
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++
« Ответ #14 : 25 Апрель 2013, 18:45:17 »
Ладно, по pads потом.

Сейчас я хочу изобразить код для редактирования нашего «файла». Для начала —
добавление символа в позиции курсора.

Тут нас ожидает неприятный сюрприз, связанный c кодировками. Пока сделаем
ввод только для ASCII.
Делюсь знаниями, но их у меня мало!

 

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