Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 27.08.2009, 23:38
DungeonLords DungeonLords вне форума
Активный
 
Регистрация: 21.07.2008
Сообщения: 257
Репутация: 14
Сообщение Поиск внутри файлов

Помогите решить проблему.

Задача. Есть много файлов с расширением PAS (сколько не известно) в одной папке PAPKA. В них объявлено x классов (сколько именно неизвестно). Нужно произвести поиск классов и их предков (то есть того, что написано в скобках после "= class") во всех файлах с расширением PAS в папке PAPKA и записать в текстовой документ ProjectClasses. Но при этом есть одно очень важное замечание. Не у всех классов есть предки! Так же проблема с тем, что в строке с имянем класса и его предка/предков может быть произвольное количество пробелов, но стоит обратить внимание, что ВСЕГДА объявление класса и его предка/предков будет на одной строке.

Конечно в идеале я бы хотел, чтобы компьютер составлял иерархическое древо классов (как во многих книгах по Delphi), но понимаю, что эта задача очень трудна.

Заранее благодарен за любые ответы.

P.S. Впринципе расскажите хотя бы как тупо производить поиск в файлах через Delphi, это информация уже бует очень важна.
__________________
Делаем'c разные игры. Искать на glscene.ru
Ответить с цитированием
  #2  
Старый 28.08.2009, 00:33
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Не вижу больших сложностей.
Алгоритм примерно такой:

1. Открываем файл.
2. Построчно анализируем. Ищем вхождение "=class" в строке предварительно убрав все ненужные пробелы.
2.1. В случае нахождения, записываем в ветку дерева имя класса
2.2. Проверяем, является ли данный класс наследником ища в строке "=class(". Получаем имя предка.
2.2.1. В случае успеха переподчиняем ветку дерева ветке с именем предка. Если такой ветки еще не существует предварительно создаем ее.
Выполняем п.2
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #3  
Старый 28.08.2009, 08:59
DungeonLords DungeonLords вне форума
Активный
 
Регистрация: 21.07.2008
Сообщения: 257
Репутация: 14
По умолчанию

Да, вроде все ok, но...

Цитата:
Сообщение от Страдалецъ
Не вижу больших сложностей.
Алгоритм примерно такой:
2. Построчно анализируем. Ищем вхождение "=class" в строке предварительно убрав все ненужные пробелы.
Ага, предлагаешь собственолично убрать все пробелы в 200 юнитах ?
__________________
Делаем'c разные игры. Искать на glscene.ru
Ответить с цитированием
  #4  
Старый 28.08.2009, 09:14
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,906
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

Цитата:
Сообщение от DungeonLords
Да, вроде все ok, но...


Ага, предлагаешь собственолично убрать все пробелы в 200 юнитах ?

Давно я так заразительно не смеялся... А компьютер тебе зачем???
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #5  
Старый 28.08.2009, 09:29
DungeonLords DungeonLords вне форума
Активный
 
Регистрация: 21.07.2008
Сообщения: 257
Репутация: 14
По умолчанию

Вопрос такой - как сделать игнорирование пробелов? Оба класса, объявленных ниже, должны попадать в список:
Код:
Syper = class (men)
Код:
Beautiful= class    (mensha)
. Как быть?

Цитата:
Сообщение от Aristarh Dark
А компьютер тебе зачем???
Чтоб беречь клавиотуру .
__________________
Делаем'c разные игры. Искать на glscene.ru
Ответить с цитированием
  #6  
Старый 28.08.2009, 17:58
DungeonLords DungeonLords вне форума
Активный
 
Регистрация: 21.07.2008
Сообщения: 257
Репутация: 14
По умолчанию

И ещё вопрос, как узнать сколько файлов лежит в папке PAPKA?
__________________
Делаем'c разные игры. Искать на glscene.ru
Ответить с цитированием
  #7  
Старый 28.08.2009, 18:11
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Ну никак непредполагал, что моя невинная фраза:
Цитата:
2. Построчно анализируем. Ищем вхождение "=class" в строке предварительно убрав все ненужные пробелы.
может быть так истолкована:
Имелось ввиду следующее: читаем строку(именно текущую стоку, а не весь юнит), прогоняем ее через S := StringReplace(S,#32#32,#32,[rfReplaceAll])

А получить количество нужных файлов можно так:
Код:
Var
  FileInfo: TSearchRec;
  FileCount: Integer;
begin
 FindFirst('c:\1\*.JPG', faAnyFile, FileInfo);
 FileCount := 0;
 repeat
  Inc(FileCount);
 until FindNext(FileInfo) <> 0;
 ShowMessage(IntToStr(FileCount));
end;
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.

Последний раз редактировалось Страдалецъ, 28.08.2009 в 18:35.
Ответить с цитированием
  #8  
Старый 28.08.2009, 21:40
DungeonLords DungeonLords вне форума
Активный
 
Регистрация: 21.07.2008
Сообщения: 257
Репутация: 14
По умолчанию

2Страдалецъ,
спасибо. Кстати, покопал, вот ещё кое-что: http://www.delphisources.ru/pages/fa...First.php.html и тут есть кое-что, чего вы не учли.

Но уже не важно. Возникла другая проблема. Я пишу:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var TXT:TextFile;
searchResult : TSearchRec;
begin 
  if FindFirst('C:\Wan.txt', faAnyFile, searchResult) = 0 then
  begin
    repeat
AssignFile(TXT,'searchResult.Name');
Reset(TXT);
CloseFile(TXT);
    until FindNext(searchResult) <> 0;

    FindClose(searchResult);
  end;
end;
Но компилятор указывает на REset и пишет, что ошибка "файл не найден", хотя он спокойно лежит по пути C:\Wan.txt!
__________________
Делаем'c разные игры. Искать на glscene.ru
Ответить с цитированием
  #9  
Старый 28.08.2009, 22:08
Drozh Drozh вне форума
Активный
 
Регистрация: 12.06.2008
Сообщения: 313
Репутация: 40
По умолчанию

Явная ошибка лежит тут
Код:
AssignFile(TXT,'searchResult.Name');
Вы указываете в качестве параметра стороку, а не переменную
Ответить с цитированием
  #10  
Старый 28.08.2009, 23:44
Аватар для Rokuell
Rokuell Rokuell вне форума
Активный
 
Регистрация: 27.12.2006
Адрес: Псков
Сообщения: 274
Версия Delphi: Delphi 7
Репутация: 497
Сообщение ClassesTree

Держите: (Исправлено 23.09.09)
http://www.delphisources.ru/forum/sh...9&postcount=26
http://www.delphisources.ru/forum/sh...0&postcount=27
__________________
Велик и могуч наш Object Pascal !
ICQ: 357-591-887

Последний раз редактировалось Rokuell, 09.11.2009 в 21:30.
Ответить с цитированием
  #11  
Старый 29.08.2009, 12:18
Аватар для Rokuell
Rokuell Rokuell вне форума
Активный
 
Регистрация: 27.12.2006
Адрес: Псков
Сообщения: 274
Версия Delphi: Delphi 7
Репутация: 497
По умолчанию ClassesTree

Пример использования:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var CT:TClassesTree;
    dir:string;
begin
 dir := 'C:\Program Files\Borland\Delphi7\Projects\PAPKA\';
 CT := TClassesTree.Create;
 try
  // исключая конструкции вида:   TClass2 = class of TClass1;
  CT.IncludeClassLinks := false;
  CT.IncludeDebugInfo := false;
  // поиск включая подпапки
  CT.GetClassesFromDir(dir,true);
  // в TreeView1 построим дерево классов
  CT.MakeTree(TreeView1); 
  // сохраним в виде дерева
  // ( можно использовать TreeView1.SaveToFile
  // результат будет одинаковый, кстати, полученный файл
  // можно будет загрузить используя TreeView1.LoadFromFile )
  CT.SaveAsTree(dir+'ClassesTree.txt');
  // сохраним в виде сортированного списка
  CT.SaveAsSortList(dir+'ClassesList.txt');
 finally
  CT.Free;
 end;
end;
__________________
Велик и могуч наш Object Pascal !
ICQ: 357-591-887
Ответить с цитированием
  #12  
Старый 30.08.2009, 20:46
DungeonLords DungeonLords вне форума
Активный
 
Регистрация: 21.07.2008
Сообщения: 257
Репутация: 14
По умолчанию

2Rokuell,
мощьно!

Но на строчке CT.SaveAsTree(dir+'ClassesTree.txt'); происходит ошибка. Конкретно в этой процедуре она происходит на строчке Rewrite(FTF);. Сама ошибка называется exception class EInOutError with message "Invalid filename". CT.SaveAsSortList(dir+'ClassesList.txt'); тоже не работатет!
__________________
Делаем'c разные игры. Искать на glscene.ru
Ответить с цитированием
  #13  
Старый 30.08.2009, 21:39
Аватар для Rokuell
Rokuell Rokuell вне форума
Активный
 
Регистрация: 27.12.2006
Адрес: Псков
Сообщения: 274
Версия Delphi: Delphi 7
Репутация: 497
По умолчанию

Цитата:
Сообщение от DungeonLords
Сама ошибка называется exception class EInOutError with message "Invalid filename".

Invalid filename - Неправильное имя файла. Проверь ещё раз, что именно передаёшь в процедуру ( существует ли папка, заданная путём dir ), т.к у меня всё работает.
__________________
Велик и могуч наш Object Pascal !
ICQ: 357-591-887

Последний раз редактировалось Rokuell, 30.08.2009 в 21:42.
Ответить с цитированием
  #14  
Старый 31.08.2009, 12:24
DungeonLords DungeonLords вне форума
Активный
 
Регистрация: 21.07.2008
Сообщения: 257
Репутация: 14
По умолчанию

2Rokuell,
ещё раз спасибо за код!!!

На деле ошибка возникала из-за того, что в папке (я забыл об этом сказать) лежал файл *.exe. Чтобы проблем не было, изменил код процедуры TClassesTree.SaveAsTree:
Код:
procedure TClassesTree.SaveAsTree(FileName: string);
var i:integer;
 function recsave(id:integer; pref:string):integer;
 var i:integer;
 begin
  if FIncludeDebugInfo then Writeln(FTF,pref+FNodes[id].name+'  ',FNodes[id].line,'  ',FNodes[id].fullpath)
  else Writeln(FTF,pref+FNodes[id].name);
  i := FNodes[id].fchildid;
  while (i<>-1) do i:=recsave(i,pref+FTabChar);
  Result := FNodes[id].nextid;
 end;
begin
 if not IsLinked then MakeLinks;
 if NOT (FileName='*.pas') then exit;
 Assign(FTF,FileName);
 Rewrite(FTF);
 i := FNodes[0].fchildid;
 while (i<>-1) do i:=recsave(i,'');
 Close(FTF);
end;
__________________
Делаем'c разные игры. Искать на glscene.ru
Ответить с цитированием
  #15  
Старый 31.08.2009, 13:16
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

1. Теги забыл))
2. выделенная строчка (ИМХО) должна иметь следующий вид:
Код:
if not ExtractFileExt(FileName)='.pas' then exit;
И не забудь, что у тебя может быть разный регистр расширений ('.pas','.PAS','.Pas','.pAs','.paS' и т.п. - РАЗНЫЕ строки)
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj

Последний раз редактировалось PhoeniX, 31.08.2009 в 13:19.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 17:44.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter