Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Подскажите, как работать с текстовыми файлами (отк 
:(
    Опции темы
Гость_fly
Дата 1.8.2003, 11:44 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Ув. программисты и не только...
Вследствие отсутствия нвавыков работы и программирования на VC++, у меня есть проблема - мне необходимо открыть и переформатировать текстовый файл согласно кодам ASCII.


Подскажите, пожайлуста, какие команды для этого использовать, в каком порядке, и где про это написано.

Заранее благодарен...
  Вверх
Step
Дата 1.8.2003, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5151
Регистрация: 26.9.2002
Где: дурдом.UA

Репутация: 5
Всего: 25



CStdioFile МFC класс для открытия файла и работы с ним или СFile


--------------------
- Дурак учится на своих ошибках, умный на чужих.
 - умные учатся у дураков
PM MAIL ICQ   Вверх
mr.DUDA
Дата 1.8.2003, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



А что значит
Цитата
переформатировать текстовый файл согласно кодам ASCII

Перевести из какой-то кодировки в ASCII ?
Заменить все символы HEX-кодами ?
adv/gulp.gif


--------------------
user posted image
PM MAIL WWW   Вверх
dmitryfly
Дата 2.8.2003, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 1.8.2003

Репутация: нет
Всего: нет



Нет, надо отформатировать любой текст для просмотра в выбранных размерах окна, т.е. убрать старые "Энтеры" и расставить новые согласно необходимой ширине, плюс к этому проблемы корректного открытия и закрытия текстового файла.
PM MAIL   Вверх
DENNN
Дата 2.8.2003, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 3878
Регистрация: 27.3.2002
Где: Москва

Репутация: 1
Всего: 43



Для начала скажи, насколько C++ владеешь. А то вопросы вызывают смутные подозрения......
PM ICQ   Вверх
mr.DUDA
Дата 2.8.2003, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



Для чего переформатировать текст, если при выводе в окно ч/з DrawText можно указать bounding rectangle ?


--------------------
user posted image
PM MAIL WWW   Вверх
dmitryfly
Дата 3.8.2003, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 1.8.2003

Репутация: нет
Всего: нет



Владею BorlandC хорошо, но в MS VC++ начал работать с 10 июля с.г., т.к. это мое задание по практике в универе, а курсов по ООП еще не было, только осенью начнутся......

Так что MS VC++ для меня пока, к сожалению, не очень понятен, мягко говоря.


2 mr.DUDA: вследствие вышесказанного, о DrawText и его св-вах я ничего не знаю....
PM MAIL   Вверх
mr.DUDA
Дата 3.8.2003, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



Допустим, есть окно (с обработчиком OnPaint) и процедура, которая открывает и читает весь файл в глобальный массив (я упрощаю, не привязываясь к Document/View и Serialize; просто абстрактный пример для общего понятия). Итак, ф-ция ReadMyFile читает весь файл в массив char *text, а обработчик CMyWnd::OnPaint() отображает содержимое этого массива:
Код

char    *text = NULL;
//  ..........
BOOL   ReadMyFile(CString csFileName)
{
   CFile file;
   if(!file.Open(csFileName, CFile::modeRead)) return FALSE;
   if(text) delete text;
   DWORD len = file.GetLength();
   text = new char[len];
   file.Read(text, len);
   return TRUE;
}
//  ..........
void    CMyWnd::OnPaint()
{
   CPaintDC dc(this);
   if(!text) if(!ReadMyFile("C:\\1.txt")) return;
   CRect rect;  GetClientRect(&rect);
   dc.DrawText(text, strlen(text), &rect, DT_LEFT|DT_TOP|DT_WORDBREAK);
}


P.S. Кстати, метод CDC::DrawText пришел в MFC из Win32 API (как и 80-90% остальных ф-ций и методов)

Это сообщение отредактировал(а) mr.DUDA - 3.8.2003, 12:05


--------------------
user posted image
PM MAIL WWW   Вверх
p0s0l
Дата 3.8.2003, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 2
Всего: 112



Полагаться полностью на DrawText нельзя. Пример:
в файле:
abc def ghi
klm

При выводе, abc def поместилось в первую строку, но ghi перенесся на следующую. А klm будет рисоваться из-за ентера уже в третьей строке, хотя он вполне бы влез во вторую строчку.
Т.е. при чтении файла надо убирать все ентеры... Но тут проблемка - исчезнут абзацы.



--------------------
С уважением, г-н Посол.
PM   Вверх
mr.DUDA
Дата 3.8.2003, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



Непонятна суть проблемы. Если есть форматированный текст, то слово N будет начинаться с новой строки в любом случае, если даже слово (N-1) было перенесено на новую строку из-за того что оно не помещалось в строке M. Пример - Word, если набрать строку из 2-х очень длинных слов, нажать Enter и набрать третье длинное слово с новой строки, то 2-е слово будет перенесено на новую строку из-за своей длины, а 3-е слово - из-за Enter'a. То же самое относится и к коротким словам - можно сделать так, что последнее слово из 2-х букв будет перенесено на новую строку, а следующее слово будет после Enter'a (опять с новой строки).

Если же просто убрать все Enter'ы, то как ты определишь, где автор текста вставил "\n", чтобы сделать новый абзац ? Никак.

Твой пример с "ghi" - не пример "из жизни", таких узких окон не бывает smile.gif , я соглашусь если это toolbar (но тогда зачем Enter'ы в тексте), а если речь идет о текстовом редакторе - ну зачем делать его шириной в 100px ??


--------------------
user posted image
PM MAIL WWW   Вверх
p0s0l
Дата 3.8.2003, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 2
Всего: 112



Хочешь пример "из жизни"?

Поверх пустыни вспыхивает многоцветье дип-программы. Секунду я еще\n
видел экранчики, мягкую подкладку шлема, потом сознание начало плыть. Мозг\n
пытался сопротивляться, но куда там! Дип-программа действует на всех.\n

Предположим, что ширина окна позволяет в первой строчке уместиться этой строке:
Поверх пустыни вспыхивает многоцветье дип-программы. Секунду
На второй строчке останется только: я еще

В результате:
Поверх пустыни вспыхивает многоцветье дип-программы. Секунду
я еще
видел экранчики, мягкую подкладку шлема, потом сознание начало
плыть. Мозг
пытался сопротивляться, но куда там! Дип-программа действует на
всех.


Это что - нормально ? Ощущение такое, что текст написан через строчку, "обрезки" все портят...
Я в таком виде ни за что не стал бы читать...

Это сообщение отредактировал(а) p0s0l - 3.8.2003, 16:13


--------------------
С уважением, г-н Посол.
PM   Вверх
dmitryfly
Дата 3.8.2003, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 1.8.2003

Репутация: нет
Всего: нет



2mr.DUDA:
Я прочитал код и я понимаю сам алгоритм и что происходит при действии каждого оператора, но проблема в том, что я не знаю, что и куда располагать, а также объясни пожалуйста, что такое обработчик OnPaint() икак мне всё-таки написать мою программу.....

2all:

это так, при удалении всех Энтеров абзацы могут потеряться, но а если отслеживать не только \n, но и комбинации символов, типа: "\n\n"(2 Энтера подряд),"\n_"(т.е. пробелы после переноса каретки на новую строку),"\n\t"(Tab после начала строки), т.к. в данном случае ясно, что автором выделяется абзац... В таком случае удаление всех Энтеров кроме данных случаев и их комбинаций, типа "\n\n\t" или "\n\n\n_" и т.д., будет оправдано...

Спасибо Всем за Ваше всеобщее внимание, надеюсь на вашу дальнейшую Вашу помощь......
PM MAIL   Вверх
p0s0l
Дата 3.8.2003, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 2
Всего: 112



Цитата
а если отслеживать не только \n, но и комбинации символов, типа: "\n\n"(2 Энтера подряд),"\n_"(т.е. пробелы после переноса каретки на новую строку),"\n\t"(Tab после начала строки)

Как раз это и хотел предложить... Думаю, что в большинстве текстов есть отсуп в начале абзаца.



--------------------
С уважением, г-н Посол.
PM   Вверх
mr.DUDA
Дата 3.8.2003, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



Начну с того, что не всегда и не обязательно в текстовом файле в конце каждой строки стоит "\n". Чаще встречается случай когда их нету, тогда редактор/вьювер самостоятельно переносит строки (word-wrapping). Ладно, пусть будут "\n"; кстати, в Win добавляется еще и "\r" (в отличие от Линукса), если кто не верит - откройте Блокнот, нажмите Enter, сохраните, откройте любым HEX-вьювером. Что мы видим ? "0D 0A" ? Так это и есть "\n\r".

Давайте тогда будем заменять все встречающиеся последовательности "\n_", "\n\t", "\n\t\t", "\n__" и т.д. на "\n\t", а все переносы конца строк уберем нафиг. Чтобы не ошибиться, будем искать "правильные" абзацы и заменять их на спец. последовательность символов, а оставшиеся переводы строк ("левые" переносы) убивать безжалостно.

С учетом вышесказанного, последовательность действий такова (to dmitryfly):

1) Создаешь проект MFC EXE (Single document), допустим обзываешь его Editor - получаешь набор классов "CEditorDoc", "CEditorView" и др. (нам будут нужны только эти два класса).

2) Добавляешь переменную "CString text" в класс CEditorDoc:
Код

class CEditorDoc : public CDocument
{
// .........................
// Attributes
public:
   CString  text;   ///     <--------- сюда будет грузиться текст


3) Вносишь изменения в функцию CEditorDoc::OnNewDocument:
Код

BOOL CEditorDoc::OnNewDocument()
{
   if (!CDocument::OnNewDocument())
       return FALSE;
   text = "";  /// <-------- стираем всё предыдущее содержимое
   return TRUE;
}


4) Заходишь в функцию CEditorDoc::Serialize(CArchive &ar), изменяешь ее так:
Код

void CEditorDoc::Serialize(CArchive& ar)
{
   if (ar.IsStoring())
   {
       // Нечего нам сохранять
   }
   else
   {
       DWORD len = ar.GetFile()->GetLength();
       char *buf = new char[len];         // создаем временный буфер
       ar.Read(buf, len);                       // читаем в него весь файл
       text = buf;                                  // копируем текст в CString text
       delete buf;                                  // сносим буфер нафиг
       // теперь разбираемся с абзацами и удаляем "левые" переносы строк
       text.Replace("\n\r", "\n");            // делаем переносы как в Линуксе :)
       text.Replace("\n ", "%%beg");     // заменяем абзац на спец. символ
       text.Replace("\n\t", "%%beg");   // то же самое для др. вида абзаца
       text.Replace("\n", "");                  // убираем оставшиеся переносы
       text.Replace("%%beg", "\n\t");   // восстанавливаем абзацы
   }
}

5) Наконец, заходишь в функцию CEditorView::OnDraw и пишешь:
Код

void CEditorView::OnDraw(CDC* pDC)
{
   CEditorDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   CRect rect;
   GetClientRect(&rect);
   pDC->DrawText(pDoc->text, &rect, DT_LEFT|DT_TOP|DT_WORDBREAK);
}


Скомпилировав, ты получаешь полноценное приложение, способное открывать файлы любого формата и отображать их содержимое. При этом, сами данные хранятся в объекте "документ", а объект "представление" только отображает их.
Если хочешь быстро и не напрягаясь сделать прокрутку по горизонтали и вертикали, выбирай на последнем шаге создания проекта вместо класса "CView" класс "CScrollView", и добавь перед строкой "pDC->DrawText(...)" следующий код:
Код

    rect.InflateRect(0, 0, GetScrollPos(SB_HORZ), GetScrollPos(SB_VERT));

Также увеличь в методе "CEditorVew::OnInitialUpdate()" размер прокрутки по вертикали:
Код

   sizeTotal.cx = 100;
   sizeTotal.cy = 5000;  // вообще-то расчитывать размер прокрутки
                                     // нужно самостоятельно, но пока и так сойдет


Если хочешь найти инфу как сделать круче - тебе сюда.

Засим откланиваюсь smile.gif

Это сообщение отредактировал(а) mr.DUDA - 3.8.2003, 19:12


--------------------
user posted image
PM MAIL WWW   Вверх
PostEr
Дата 3.8.2003, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 282
Регистрация: 30.6.2003
Где: Самара

Репутация: 1
Всего: 1



mr.DUDA, твой тутор просто рулез! А нельзя объяснить что за классы такие
Цитата
"CEditorDoc", "CEditorView" и др.



--------------------

------------------------------------------------------------------

[email protected]
До востребования

PM MAIL WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0809 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.