IPB
ЛогинПароль:

> 

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

2 страниц V  1 2 >  
 Ответить  Открыть новую тему 
> проблемы работы с директориями
сообщение
Сообщение #1





Группа: Пользователи
Сообщений: 6
Пол: Мужской

Репутация: -  0  +


Есть много вопросов по работе в BP7, TMT (3.90), FPC (2.4.0.i386-win32) под WinXP:
1) верно ли, процедуры FindFirst и FindNext могут одновременно работать с несколькими директориями и даже с одной директорией через несколько указателей;
2) верно ли, что указатель поиска в директории определяется только записью файла SR (тип TSearchRec), но не директорией в которой она расположена, т.е. только по записи файла SR возможно непосредственно определить ее директорию и ее расположение в директории;
3) верно ли, что вызов FindNext(SR) возвращает в SR следующую запись (если она есть, если нет - SR неопределено или исходное значение?) в директории ее (исходной записи SR) расположения, а не в директории из последнего вызова процедуры FindFirst;
4) верно ли, что вызов FindClose(SR) прекращает поиск (работу с указателем) в директории расположения записи, а не в директории из последнего вызова процедуры FindFirst, поиск в других директориях не прекращается (непонятно, зачем вообще нужна эта процедура, если вся работа идет с данными из записи SR);
- без выполнения данных взаимосвязанных утверждений рекурсивный поиск в директориях НЕВОЗМОЖЕН (по крайней мере, без создания списков их содержимого),

далее:
5) верно ли, что путь к директории в вызове процедуры FindFirst должен заканчиваться разделителем '\';
6) возможна ли проверка существования файла, директории или лог. диска по его имени/полному_имени без использования процедур FindFirst и FindNext;
7) возможна ли работа с текущей директорией (получение абс. пути, изменение);
8) верно ли, что имена директорий SR.name в их записях SR из их наддиректорий не содержат разделителя '\';
9) верно ли, что записи в любой не изменившейся директории при каждой ее обработке процедурами FindFirst и FindNext выдаются в одном и том же порядке (лексикографическом по именам?);
10) как обеспечить работу с длинными именами файлов (как вызвать Win под FPC);
11) верно ли, что поле Time в TSearchRec - это время создания файла (если нет, как узнать/изменить время создания), или это время его последнего изменения/открытия;
12) что представляют собой неизвестные компилятору типы полей записи SR файла в директории под Win: TFileName (=string ?), THandle, TWin32FindData, каким характеристикам файла они и Fill (тип array[1..21] of Byte) отвечают;
Win32 target
type
TSearchRec = record
Fill : array[1..21] of Byte;
Attr : Byte;
Time : Longint;
Size : Longint;
Name : TFileName;
ExcludeAttr : Longint;
FindHandle : THandle;
FindData : TWin32FindData
end;


--------------------
взять бы всех программистов - да утопить
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Ты для начала переведи то, что написано выше на нормальный русский язык...

Цитата
верно ли, что вызов FindNext(SR) возвращает в SR следующую запись (если она есть, если нет - SR неопределено или исходное значение?) в директории ее (исходной записи SR) расположения, а не в директории из последнего вызова процедуры FindFirst;
Это что тут написано, можно объяснить? Какая директория последнего вызова FindFirst? Какая директория "ее (исходной записи SR) расположения"? Ты о чем вообще?

Чтобы инициировать поиск файлов вызывается FindFirst с указанием папки и маски для имени файла. Если файл, имя которого соответствует маске, найден - DosError = 0 (и SR содержит корректные данные), если нет - DosError = 18. Потом продолжаем искать файлы в той же папке, где начали FindFirst-ом, но уже с использованием FindNext. То же самое: файл найден - DosError = 0, не найден, значит = 18... Не надо полагаться на содержимое SR в случае, когда файл не был найден. Произошла ошибка, это - все, что надо знать. Ошибка - значит, нет веры тому результату, который вернулся...

Цитата
верно ли, что вызов FindClose(SR) прекращает поиск (работу с указателем) в директории расположения записи, а не в директории из последнего вызова процедуры FindFirst, поиск в других директориях не прекращается (непонятно, зачем вообще нужна эта процедура, если вся работа идет с данными из записи SR);
Директория расположения записи - это что? Запись располагается в памяти, если что... Терминология твоя ошибочна, задай вопросы с нормальной терминологией. И напиши, наконец, кусок кода, в котором у тебя получается не то поведение, которого ты ожидаешь... Не заставляй других угадывать, как это делал ты...

Цитата
непонятно, зачем вообще нужна эта процедура, если вся работа идет с данными из записи SR
Ответ выделен:
Цитата(rtl.pdf стр 299)
FindClose frees any resources associated with the search record F.
This call is needed to free any internal resources allocated by the FindFirst or FindNext calls.


Цитата
без выполнения данных взаимосвязанных утверждений рекурсивный поиск в директориях НЕВОЗМОЖЕН (по крайней мере, без создания списков их содержимого)
А мужики-то не знают, и уже десятки лет используют рекурсивный поиск в папках/подпапках... Если ты чего-то не осилил, не надо говорить, что это невозможно... В общем, пример, как пытался - в студию... Больше я догадываться не собираюсь... Будет код - будет разговор.

Цитата
верно ли, что путь к директории в вызове процедуры FindFirst должен заканчиваться разделителем '\';
Первый параметр FindFirst - это маска имени файла, соответствие которой проверяется. И ничего больше.

Цитата
что представляют собой неизвестные компилятору типы полей записи SR файла в директории под Win
Компилятору все прекрасно известно. Повторяю: эти функции используются не первый год, если что-то неизвестно - ошибку ищи у себя в коде, значит, неверно вызываешь... Телепаты с форума ушли...

Добавлено через 7 мин.
P.S.
То, чаво на белом свете, вообче не может быть! (по крайней мере - по твоему утверждению).

{$TELEPATHY ON}
P.P.S. Разницу между локальными и глобальными переменными хорошо понимаешь? Корень твоей проблемы - в этом...
{$TELEPATHY OFF}

Цитата
9) верно ли, что записи в любой не изменившейся директории при каждой ее обработке процедурами FindFirst и FindNext выдаются в одном и том же порядке (лексикографическом по именам?);
Нет. Это зависит от ОСи, зависит от используемой файловой системы. Вот что по этому поводу говорит MSDN:

Цитата
The order in which the search returns the files, such as alphabetical order, is not guaranteed, and is dependent on the file system. If the data must be sorted, the application must do the ordering after obtaining all the results.

Note In rare cases, file attribute information on NTFS file systems may not be current at the time you call this function. To be assured of getting the current NTFS file system file attributes, call the GetFileInformationByHandle function.

The order in which this function returns the file names is dependent on the file system type. With the NTFS file system and CDFS file systems, the names are usually returned in alphabetical order. With FAT file systems, the names are usually returned in the order the files were written to the disk, which may or may not be in alphabetical order. However, as stated previously, these behaviors are not guaranteed.
(отсюда: MSDN -> FindNextFile Function)
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3





Группа: Пользователи
Сообщений: 6
Пол: Мужской

Репутация: -  0  +


Цитата(volvo)
Цитата(ddn)
верно ли, что вызов FindNext(SR) возвращает в SR следующую запись (если она есть, если нет - SR неопределено или исходное значение?) в директории ее (исходной записи SR) расположения, а не в директории из последнего вызова процедуры FindFirst;
Это что тут написано, можно объяснить? Какая директория последнего вызова FindFirst? Какая директория "ее (исходной записи SR) расположения"? Ты о чем вообще?
(Dir1<>Dir2)
FindFirst(Dir1+mask1, Attr1, SR1); (* Dir1 - директория расположения записи SR1 *)
FindFirst(Dir2+mask2, Attr2, SR2); (* Dir2 - директория расположения записи SR2 и директория последнего вызова FindFirst *)
FindNext(SR1);
FindClose(SR1) либо FindClose(SR2);

- FindNext(SR1) ищет следующую запись в директории Dir1 расположения записи SR1 или ищет в последней вызванной FindFirst директории Dir2 игнорируя значение SR1 ?; нужно ли вообще значение SR1 для поиска, или только для присвоения результата ?;
-- ...присваивая следующую запись значению SR1, если она найдена, каковым делает значение SR1, если она не найдена: делает неопределенным, оставляет прежнее (возможно непроинициированное), каким угодно (в т.ч. ошибочным) ?;
--- можно ли из значения SR получить указатель поиска в директории, используется ли это в FindNext(SR) ?; а получить маску и атрибуты поиска, и вообще отнести SR по ее имени к конкретному вызову поиска FindFirst(Dir+mask, Attr, SR) ? (ведь значение SR мы можем присвоить другой переменной SR0 и работать уже с ней: FindNext(SR0), FindClose(SR0) - как мы (т.е. программа) определим по имени SR0 к какому вызову поиска она относится? если поисков допускается несколько одновременно - разве что по значению SR0);
Быть может следует говорить не о директории поиска, а о самом поиске, с конкретными параметрами: директория, маска имени файла, атрибуты (привязан он к конкретному имени SR, или определяется через значение SR - неясно);

Цитата(volvo)
Цитата(ddn)
верно ли, что вызов FindClose(SR) прекращает поиск (работу с указателем) в директории расположения записи, а не в директории из последнего вызова процедуры FindFirst, поиск в других директориях не прекращается (непонятно, зачем вообще нужна эта процедура, если вся работа идет с данными из записи SR);
Директория расположения записи - это что? Запись располагается в памяти, если что... Терминология твоя ошибочна, задай вопросы с нормальной терминологией. И напиши, наконец, кусок кода, в котором у тебя получается не то поведение, которого ты ожидаешь... Не заставляй других угадывать, как это делал ты...
Директория расположения записи файла SR - это директория, откуда она была прочитана процедурой FindFirst или FindNext (где расположен отвечающий SR файл);
---- прекращает ли вызов FindFirst(Dir2+mask2, Attr2, SR2) поиск в директории Dir1, сбрасывая его указатель ? (т.е. допустим только один поиск единовременно?);
----- прекращает ли аналогично вызов FindClose(SR1) поиск в директории Dir2, а вызов FindClose(SR2) поиск в директории Dir1 ?;

Цитата(volvo)
Ответ выделен:
Цитата((rtl.pdf стр 299))
FindClose frees any resources associated with the search record F.
This call is needed to free any internal resources allocated by the FindFirst or FindNext calls.
FindClose(SR) освобождает любые ресурсы ВСЕХ поисков ? (зачем параметр SR ?); или все-таки в последнего поиска вызванного FindFirst, или поиска соответствующего значению SR ?;
В хелпе TMT ее нет, а у FPC вообще нет хелпа. Где-то на форуме видел пример с FindClose.

Цитата(volvo)
Цитата("ddn")
что представляют собой неизвестные компилятору типы полей записи SR файла в директории под Win
Компилятору все прекрасно известно. Повторяю: эти функции используются не первый год, если что-то неизвестно - ошибку ищи у себя в коде, значит, неверно вызываешь... Телепаты с форума ушли...
Я имел в виду, что в хелпе их нет.
Что до ошибки, то пока до этого дело не дошло. У меня написана программка, но отладчика нет, а почему не компилируется (TMT, FPC): может синтаксическая мелочь какая, а может и тип неизвестен (ведь TSearchRec еще правильно вызвать нужно) - непонятно.
Вот на BP7 есть отладчик, но какой! Вот он писал, что тип TSearchRec неизвестен - ладно, описал его явно (в Dos-варианте), функции max и min тоже неизвестны - их можно смоделировать; uses Dos - Error 15: File not found (DOS.TPW). - ладно, обойдемся; но дальше он даже простые вещи перестал принимать, и я сделал совсем простую программу!
program cd (dir1, dir2: string);
begin
dir1=dir2
end.
все равно выдает Error 89: ')' expected. (курсор на ':'), притом еще недавно на ту же самую программу выдавал что-то ... ':=' ... (курсор на '='). Ну как тут быть?!
Странный отладчик и странный компилятор.
Поэтому, я пока пытаюсь выяснить, как там в теории должно действовать (может я вообще неправильно что-то понимаю), чтобы не блуждать впотьмах, гадая, где там ошибка может быть.

Цитата(volvo)
То, чаво на белом свете, вообче не может быть! (по крайней мере - по твоему утверждению).
Я видел этот пример. Хотя я стараюсь не использовать рекурсию, стараюсь сделать стек через file или array. Эта же рекурсия меня насторожила, она усилила мои подозрения, что допустим только один поиск единовременно.
Цитата(volvo)
{$TELEPATHY ON}
P.P.S. Разницу между локальными и глобальными переменными хорошо понимаешь? Корень твоей проблемы - в этом...
{$TELEPATHY OFF}
Насчет проблемы с компиляцией - незнаю, а вот насчет проблем с пониманием работы FindFirst и FindNext - да. Да, я тоже тогда подумал про какие-то странные грязные трюки с глобальными переменными (в данном случае это параметры поиска). Если в внутри одной процедуры, то только один поиск единовременно - неявная глобальная переменная инициируемая FindFirst, то в разных вызовах - своя переменная поиска, локальная. Разве значение глобальной переменной не передается из тела процедуры внутрь всех процедурных вызовов в ней?

Цитата(volvo)
Цитата(ddn)
без выполнения данных взаимосвязанных утверждений рекурсивный поиск в директориях НЕВОЗМОЖЕН (по крайней мере, без создания списков их содержимого)
А мужики-то не знают, и уже десятки лет используют рекурсивный поиск в папках/подпапках... Если ты чего-то не осилил, не надо говорить, что это невозможно... В общем, пример, как пытался - в студию... Больше я догадываться не собираюсь... Будет код - будет разговор.
Я имел ввиду, что невозможен, если допустим только один поиск единовременно.
С компилятором Паскаля я только начинаю работать. До этого я программировал в Мапле - исполняемая среда символьных вычислений, эрзац Паскаля/Модулы без статической типизации. Но работа с файлами неустраивала меня, слишком невнятно сделана. Мне требуется ясная работа с файлами и без ограничений.

Что до программки, которую я пишу.
Возникла потребность написать (на BP7, TMT, FPC под WinXP) процедуру для селективного копирования файлов и директорий (в том числе из вложенных директорий) из одной исходной директории в другую; структура директорий, а также атрибуты, имена, времена создания файлов и директорий сохраняются (содержимое файлов конечно тоже); селекция идет по атрибутам, имени, размеру, времени создания файла или директории.
Хотелось бы узнать, что там может быть некорректно.
Код
(* под файлами понимаются в том числе и директории *)
(*
глубина директорий c полными путями dir1 и dir2 принимается равной 0;
глубина директории = глубина расположения содержимых ею файлов, в том числе поддиректорий;
глубина директории на единицу больше глубины содержащей ее директории (наддиректории), т.е. на единицу больше глубины ее собственного расположения;
текущие директории - директории, обрабатываемые процедурами findfirst и findnext;
*)
procedure
  fullcopydir(
    dir1, dir2 : string; (* полные пути к существующим и не вложенным одна в другую директориям (т.е. пути вида '<LetterLogDisk>:\ ... \'), полное содержимое которых соответственно копируется и является результатом копирования *)
    prov : boolean; (* флаг необходимости проверки путей dir1 и dir2 на невложенность *)
    sel : function(
      attr : byte;
      time : longint;
      size : longint;
      name : string (* string[12] *)
    ) : boolean (* функция селекции на копирование для вложенных файлов, по некоторым полям их записи; поддиректории '.' и '..' игнорируются *)
  );
const
  maxh = 127; (* предел глубины расположения файлов *)
type
  t = record
    b : boolean; (* флаги обнаружения требуемых селекцией файлов в текущих вложенных директориях, либо требуемости самих этих директорий  *)
    ln : byte; (* длины полных путей к текущим вложенным директориям *)
    dir : string; (* относительные (от dir1) пути к текущим вложенным директориям *)
    sr : tsearchrec (* записи (в их наддиректориах) текущих вложенных директорий *)
  end;
var
  e : boolean;
  i : byte;
  c : t;
  f, d : file;
  h : 0..maxh; (* глубина расположения непосредственно обрабатываемого файла *)
  b : boolean; (* флаг обнаружения требуемых файлов в директории расположения непосредственно обрабатываемого файла *)
  ln : byte; (* длина полного пути к директории расположения непосредственно обрабатываемого файла *)
  sr : tsearchrec; (* запись непосредственно обрабатываемого файла в директории его расположения *)
  r : file of t;
begin
  if prov then
    begin
      ln := min(length(dir1), length(dir2));
      i := 1;
      while i<=ln and dir1[i]=dir2[i] do
        i := i+1;
      if i>ln then
        halt('исходные директории вложены')
    end;
  h := 0;
  b := true;
  ln := max(length(dir1), length(dir2));
  dir := dir1;
  e := findfirst(dir1+'*', anyfile, sr)=0;
  reset(r);
  while e do
    begin
      if (sr.attr and directory)=directory then (* запись файла отвечает директории *)
        if (sr.name='.') or (sr.name='..') then
          e := findnext(sr)=0;
        else (* приращение глубины, переход поиска в поддиректорию, создание ее копии без содержимого *)
          begin
            c.b := b;
            c.ln := ln;
            c.dir := dir;
            c.sr := sr;
            write(r, c);
            h := h+1;
            b := sel(sr.attr, sr.time, sr.size, sr.name);
            ln := ln+length(sr.name)+1;
            dir := dir+sr.name+'\';
            createdir(dir2+dir);
            assign(g, dir2+dir);
            setftime(g, sr.time);
            setfattr(g, sr.attr);
            e := findfirst(dir1+dir+'*', anyfile, sr)=0
          end
      else (* запись файла не отвечает директории *)
        begin
          if sel(sr.attr, sr.time, sr.size, sr.name) then (* копирование файла *)
            begin
              b := true;
              assign(f, dir1+dir+sr.name);
              assign(g, dir2+dir+sr.name);
              reset(f, 1);
              rewrite(g, 1);
                while not eof(f) do
                  begin
                    read(f, i);
                    write(g, i)
                  end;
              close(f);
              close(g);
              setftime(g, sr.time);
              setfattr(g, sr.attr)
            end;
          e := findnext(sr)=0 (* поиск следующей записи *)
        end;
      while (not e) and h>0 do (* возвращения из директорий до первой, где продолжение поиска результативно, либо достигнута исходная директория *)
        begin
          h := h-1;
          seek(r, h);
          read(r, c);
          seek(r, h);
          if not b then (* удаление скопированых пустых (без скопированных требуемых селекцией файлов) нетребуемых директорий  *)
            begin
              b := c.b;
              assign(g, dir2+dir);
              erase(g)
            end;
          ln := c.ln;
          dir := c.dir;
          findclose(sr);
          sr := c.sr;
          e := findnext(sr)=0
        end
    end;
  close(r)
end.


Сообщение отредактировано: ddn -


--------------------
взять бы всех программистов - да утопить
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> (* Dir1 - директория расположения записи SR1 *)

Дальше не читал. Что имеется в виду? Проходим по директории Dir при помощи записи SR1 (храня временные результаты в ней). Так и надо писать.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5





Группа: Пользователи
Сообщений: 6
Пол: Мужской

Репутация: -  0  +


Цитата(TarasBer @ 13.07.2010 14:59) *
> (* Dir1 - директория расположения записи SR1 *)

Дальше не читал. Что имеется в виду? Проходим по директории Dir при помощи записи SR1 (храня временные результаты в ней). Так и надо писать.
Записи файла расположенной в бинарном содержимом директории, а отвечающего ей файла - содержащегося в директории.

Первоначально, я решил что SR просто вспомогательная переменная, хранящая только значение элемента каталога = запись некоторого файла из этого каталога (т.е. содержащей характеристики файла и его индекс/адрес_начального_байта). Но тогда SR не привязан ни конкретному каталогу, ник его структуре, ни к маске, ни к указателю поиска. А где тогда могут храниться параметры и указатель поиска? - только в некоторой ГЛОБАЛЬНОЙ переменной ОСи одной для всех каталогов, либо по одной для каждого открытого каталога.

Потом подумал, может SR это дескриптор каталога, как при чтении любого типизированного файла (тип = каталоговый). Любой дескриптор неявно хранит положение указателя после открытия файла. Связывание и одновременное открытие с чтением первого элемента осуществляется процедурой FindFirst (вместо Assign, Reset и первого Read). Маска задается не типом SR, а при открытии (как и число считываемых байт для нетипизированных файлов) и также неявно хранится в дескрипторе. Но дескриптор не имеет компонент, ему нельзя присваивать, нельзя использовать в выражениях (присваивать его, сравнивать).

Теперь выходит, что SR это некий гибрид буферной переменной (копия паспорта файла) и дескриптора поиска.
Последний хранит (все?) параметры конкретного поиска ЛОКАЛЬНО: адрес каталога, маска, адрес текущей записи поиска, дерева поиска каталога или адреса его отдельных узлов (само дерево хранится в бинарном содержимом каталога либо создается динамически). Поскольку тип SR не ссылочный, то память под нее освобождаться не может, SR определенно содержит ссылку на какую-то безымянную динамическую структуру, создаваемую под поиск, иначе какой смысл в процедуре FindClose?
Значит можно даже в одном каталоге одновремено вести несколько независимых поисков, хотя копировать одну переменную SR в другую SR0 и затем вести независимый поиск по каждой из них все же нельзя (ведь указанная динамическая структура не скопируется так просто, останется общей для SR и SR0).
Хм, интересно, что будет, если каталог изменяется во время поиска?

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


--------------------
взять бы всех программистов - да утопить
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Цитата
моя программа в принципе должна работать правильно.
Если не работает - значит не должна. То, что должно - работает. Задачу свою озвучь, а то что-то написал, да прямо сейчас я все брошу и буду из комментариев вычленять информацию о том, что и как ты там делаешь, после Maple-то...

Цитата
Я видел этот пример. Хотя я стараюсь не использовать рекурсию, стараюсь сделать стек через file или array. Эта же рекурсия меня насторожила, она усилила мои подозрения, что допустим только один поиск единовременно.
Ты хочешь на Паскале писать в стиле Maple? Если он "не умеет" рекурсию - то это не значит, что надо ВЕЗДЕ обходиться без рекурсии, правда? Паскаль рекурсию готовить умеет, причем прекрасно. Программа получилась (заметь, в отличие от твоей) четкая, ясная и понятная. В твоей же без особого ковыряния и не разберешься.

Знаешь, в чем твоя ошибка? Это называется антипаттерн ""Золотой Молот"" Тебе кажется, что другого способа работы с вложенными папками, кроме как создание лишних сущностей в виде стека (зачем создавать стек вручную, если при использовании рекурсии это без тебя прекрасно сделает компилятор?) или файла - не существует. Однако, это не так. Существует. Рекурсия. Каждая папка - это "копия" папки - родителя, в том смысле, что работать с ней надо абсолютно так же, открыть новый поиск (кто говорил, что нельзя? Ты не закрыл первый, а уже открываешь второй, заметил?) вызвав FindFirst, потом пока не произойдет ошибка - вызывать FindNext, и в конце закрыть поиск FindClose. Всё! Больше тебя ничего не должно интересовать, заметь. Если тебе по пути встретится еще одна папка - ту просто войдешь еще глубже в рекурсию, и опять будет (автоматически!!!) сделано то же самое - FindFirst/цикл FindNext/FindClose. И (О, Чудо!!!) Когда ты выходишь из очередного уровня рекурсии на предыдущий - память высвобождена корректно, все переменные из стека удалились (это гарантирует компилятор), ничего лишнего не остается...

Чем не устраивает этот подход, можно рассказать? (только не так многословно - коротко по пунктам: раз - это плохо потому что:... ; два - это ужасно - потому что:... ; три - это неприемлемо - потому что... ; четыре - это вообще не будет работать никогда - потому что: ... ). А потом я покажу свой вариант программы. Рекурсивный. Который с большой степенью вероятности будет а) меньше, причем значительно, по размеру; б) быстрее за счет того, что не будет работать с самописным велосипедом, а будет работать с тем, с чем прекрасно умеет работать компилятор - со стеком вызовов; в) гораздо более понятной, чем твой код, ибо рекурсия. Возможно, ее сложнее написать, но читается она гораздо проще итерации, в особенности - когда итерация эту самую рекурсию эмулирует...

Цитата
Хм, интересно, что будет, если каталог изменяется во время поиска?
Получишь ошибку "и всего делов". А поскольку ты ошибки не обрабатываешь (возможно, в Maple так принято, но Паскаль - это не Maple), то просто вылетишь из программы с предложением отправить Дяде Биллу письмо...

Все, что от тебя сейчас требуется - это забыть все то, что ты умеешь делать в Maple, и научиться правильно работать с файлами/папками на Паскале. Как делать правильно - я тебе уже написал. Если хочешь - расскажи, что делает твой код, я напишу тебе для примера рекурсивную функцию, которая будет делать то же самое.

Цитата
Мне требуется ясная работа с файлами и без ограничений.
А ограничений и нет, если правильно пользоваться тем, что предоставляет язык. Ограничения появляются, когда ты пытаешься НАВЯЗАТЬ языку свои представления о том, как нужно делать. Не навязывай - ограничения исчезнут сами собой...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7





Группа: Пользователи
Сообщений: 6
Пол: Мужской

Репутация: -  0  +


Цитата
Если не работает - значит не должна. То, что должно - работает. Задачу свою озвучь, а то что-то написал, да прямо сейчас я все брошу и буду из комментариев вычленять информацию о том, что и как ты там делаешь, после Maple-то...
Я уже озвучил: селективное копирование файлов (в том числе из вложенных директорий) из одной данной директории в другую.

Цитата
Ты хочешь на Паскале писать в стиле Maple? Если он "не умеет" рекурсию - то это не значит, что надо ВЕЗДЕ обходиться без рекурсии, правда? Паскаль рекурсию готовить умеет, причем прекрасно. Программа получилась (заметь, в отличие от твоей) четкая, ясная и понятная. В твоей же без особого ковыряния и не разберешься.
Почему, Мапл умеет рекурсию. И я знаю рекурсию. Паскалевский стиль мне ведом - структурность, описания в заголовках и т.д.

Цитата
Паскаль рекурсию готовить умеет, причем прекрасно. Программа получилась (заметь, в отличие от твоей) четкая, ясная и понятная. В твоей же без особого ковыряния и не разберешься.
Цитата
Чем не устраивает этот подход, можно рассказать? (только не так многословно - коротко по пунктам: раз - это плохо потому что:... ; два - это ужасно - потому что:...
Собственно, ничего ужасного в ней нет, просто я ей обычно не пользуюсь, так для меня прозрачнее исполнение всего алгоритма целиком (хотя кому как), пусть его код и длиннее выглядит. Для меня важно "пальцем" проследить как исполняется код от блока к блоку, а не проверять инварианты, пред- и пост- условия. Я вообще не люблю пользоваться подпроцедурами, обычно вставляю их тело прямо в теле процедуры.
Впрочем, я могу ту же процедуру написать и с рекурсией.

Цитата
быстрее за счет того, что не будет работать с самописным велосипедом...
Вызов процедур требует некоторых временнЫх затрат;
некоторые переменные для промежуточных расчетов и константы приходиться дублировать для всех рекурсивных вызовов, хотя они являются общими для всех итераций - их конечно можно сделать глобальными для всех вызовов, но придется их описать в объемлющей нерекурсивной процедуре, а рекурсивную сделать ее подпроцедурой.
Цитата
...будет работать с тем, с чем прекрасно умеет работать компилятор - со стеком вызовов...
Хм, стек имеет тенденцию переполняться, куча - куда вместительнее (правда и освобождается сложней).

Цитата
Получишь ошибку "и всего делов". А поскольку ты ошибки не отрабатываешь (возможно, в Maple так принято, но Паскаль - это не Maple), то просто вылетишь из программы с предложением отправить Дяде Биллу письмо...
Позвольте, позвольте!
Мапл ни причем, там как раз всего навалено. Стиль Паскаля - аварийный вылет при ошибке!
Обработка ошибок, операторы, возвращающие значения и коды ошибок - это СИшная ересь!

Цитата
забыть все то, что ты умеешь делать в Maple, и научиться правильно работать с файлами/папками на Паскале.
Ха, работа с файлами там (в Maple) - все тот же Дос. Там были какие-то неоднозначности с работой процедур Seek, FilePos за пределами длины файла, установки флага Eof при выполнении Read, что-то еще, + ограничения Доса.
Работа с файловой системой в Досе ужасно безыдейна, бестолково подобранный набор примитивов, в Unix получше но не идеал. В Мапле я не нашел описания полноценной работы с каталогами, решил посмотреть, что в Паскалях, а там - тот же Дос!
Ну почему нельзя было сделать расово верный идейно правильный набор примитивов работы с файловой системой - через типизированные указатели для файлов и каталогов, а работу с Dos и Win скрыть от программиста!

Цитата
Если хочешь - расскажи, что делает твой код, я напишу тебе для примера рекурсивную функцию, которая будет делать то же самое.
Я уж сам. Поскольку работа процедур поиска была мне неясной, я сомневался в самом алгоритме. Написать алгоритм для меня не проблема, проблема в спецификациях работы со всякими там Досами и Винами (я ж их не писал, почем я знаю как они действуют; инглиш я не владею), знать бы какие из модулей и как вызвать в программе, ну синтаксические мелочи исправить.

Цитата
А ограничений и нет, если правильно пользоваться тем, что предоставляет язык. Ограничения появляются, когда ты пытаешься НАВЯЗАТЬ языку свои представления о том, как нужно делать. Не навязывай - ограничения исчезнут сами собой...
Незнаю как насчет языка, в классическом Паскале вообще нет работы с внешними файлами, а вот в компиляторах полно ограничений, начиная с отсутствия отладчика и полного русскоязычного хелпа.
Как работать с длинными именами файлов, с временем создания файла, полными путями к файлам длинее 255 символов?

Сообщение отредактировано: ddn -


--------------------
взять бы всех программистов - да утопить
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Ну может ручная развёртка хвостовой рекурсии и пригодится на броландовских компиляторах.

> б) быстрее за счет того, что не будет работать с самописным велосипедом, а будет работать с тем, с чем прекрасно умеет работать компилятор - со стеком вызовов;

Может, всё-таки процессор? Инструкция call какбы.

> Хм, стек имеет тенденцию переполняться

И сколько вложенных папок надо для того, чтобы он переполнился?

> Стиль Паскаля - аварийный вылет при ошибке!
Обработка ошибок, операторы, возвращающие значения и коды ошибок - это СИшная ересь!

Чем отличается Паскаль (турбо, который без исключений) от чистого Си (без исключений) в плане обработки ошибок?

> а вот в компиляторах полно ограничений, начиная с отсутствия отладчика

ЛОЛШТО

> полными путями к файлам длинее 255 символов?

А что, в ДОСе такие бывают?
А под винду пиши на дельфи, там строки длинные.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Гость






Цитата
Может, всё-таки процессор? Инструкция call какбы.
Ну да, процессор, ОС, все что угодно. Компилятор умеет условия для работы создавать...

Цитата
Паскалевский стиль мне ведом - структурность, описания в заголовках и т.д.
Значит, плохо ведом. Паскаль не разрешает (за исключением Extended Pascal, реализуемого компилятором GPC) конструировать функциональный тип в заголовке процедуры. Сначала опиши тип-функцию, потом (в заголовке) - подставляй идентификатор этого типа.

Цитата
Стиль Паскаля - аварийный вылет при ошибке!
Обработка ошибок, операторы, возвращающие значения и коды ошибок - это СИшная ересь!
Это ты говоришь, что тебе ведом Паскалевский стиль? Если тебе так хочется думать - это твои проблемы. Вообще-то IOResult/DOSError + директива {$I} для отключения моментального вылета, как раз для того, чтобы можно было обработать ошибку - это все есть в паскале, начиная с 3-ей версии. На более старых просто не работал, возможно оно и там есть... Мало того, тебе даже предоставляются возможности (опять же, начиная как минимум с версии 5.5) искусственно создать ошибку, чтобы проверить, как твой код умеет её обрабатывать... А ты говоришь - вылет. Вылет программы в некоторых местах равносилен вылету с работы, причем еще и с занесением в черный список. Будешь потом улицы мести, если возьмут...

Цитата
Хм, стек имеет тенденцию переполняться
Хм. Ты работаешь на WinXP? Тебе не хватит допустимой вложенности папок (да, да, и у NTFS тоже есть ограничения), чтобы переполнить стек, в особенности, если пользуешься современным компилятором, таким, как FPC. В котором, кстати, размер стека можно и увеличить, если что...

Цитата
в классическом Паскале вообще нет работы с внешними файлами
А в Паскале ее и не должно быть. Должно быть обращение к функциям ОС для того, чтобы на этой ОС уже работать с ее функциями (насчет бестолковости или толковости - это ты сначала на свой код посмотри, а потом будешь WinAPI обсуждать). Если Турбо-Паскаль был написан в то время, когда кроме DOS ничего не было (а если и было - то TP там не запускался), то ничего кроме Uses DOS в языке и быть не должно. То, что ты запускаешь TP под Windows - это ни разу не проблема Паскаля. Это проблема твоя. Есть компиляторы под Windows - пользуйся ими, там прекрасно реализована работа с WinAPI. Или вообще кроссплатформенные версии - но за это будешь платить размером исполняемых файлов, в частности. Не веришь? Запусти Лазарус и откомпилируй приложение, показывающее форму с одной кнопкой. 12Мб EXE-шник тебе обеспечен. Дельфи (упс, это же только Windows, может поэтому размер EXE-шника меньше? Не надо заботиться о том, как этот же код должен компилироваться в другой ОС, не надо делать обертки разные?) тебе в таком случае уложится в 200К, а на чистом API можно и в 30К уложиться (но это еще ближе к ОСи, замечаешь?). Ты все еще хочешь универсальности, чтоб можно было из любой ОСи работать с функциями ОС однотипно?

Цитата
а вот в компиляторах полно ограничений, начиная с отсутствия отладчика
Вообще-то и отладчик и IDE идет в стандартной установке FPC, которая качается с официального сайта. Я уж не знаю, чего ты там качал, что у тебя отладчика не оказалось.

Цитата
Ну почему нельзя было сделать расово верный идейно правильный набор примитивов работы с файловой системой - через типизированные указатели для файлов и каталогов, а работу с Dos и Win скрыть от программиста!
И чем тебе FPC-шный FindFirst (из модуля SysUtils) - не расово верный? Работает и под ДОС, и под Windows, да и Unix-ы тоже не забывает. Я ж не виноват, что кое-кто не умеет читать доки, правда?

Цитата
Как работать с длинными именами файлов, с временем создания файла, полными путями к файлам длинее 255 символов?
Пользоваться современными компиляторами, в них нет этого ограничения. Либо сторонними модулями (типа LDos) для старых компиляторов.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10





Группа: Пользователи
Сообщений: 6
Пол: Мужской

Репутация: -  0  +


Цитата
> Хм, стек имеет тенденцию переполняться

И сколько вложенных папок надо для того, чтобы он переполнился?
В общем случае. Рекурсия не только для вложенных папок.

Цитата
> Стиль Паскаля - аварийный вылет при ошибке!
Обработка ошибок, операторы, возвращающие значения и коды ошибок - это СИшная ересь!

Чем отличается Паскаль (турбо, который без исключений) от чистого Си (без исключений) в плане обработки ошибок?
Турбо Паскаль не вполне Паскаль. Паскаль предупреждает ошибки, а не обрабатывает.
Иначе, зачем Eof если есть IOResult ?

Цитата
> а вот в компиляторах полно ограничений, начиная с отсутствия отладчика

ЛОЛШТО
Отладчик это компенсация плохого хелпа. Не кристально ясный, неполный, не родного языка хелп - это не хелп. Интерфейс без хелпа (кроме интуитивно ясного примитива) - не интерфейс. Софт без интерфейса - неработающий софт.

Цитата
> полными путями к файлам длинее 255 символов?

А что, в ДОСе такие бывают?
А под винду пиши на дельфи, там строки длинные.
Что толку в длинных строках, сомневаюсь что сами файловые процедуры Assign, FindFirst с ними работают.
Не знаю как с этим в Дельфи, но это еще более громоздкая, более сложная для изучения вещь, чем BP и FPC.

Цитата
Значит, плохо ведом. Паскаль не разрешает (за исключением Extended Pascal, реализуемого компилятором GPC) конструировать функциональный тип в заголовке процедуры. Сначала опиши тип-функцию, потом (в заголовке) - подставляй идентификатор этого типа.
У Йенсена Вирта "ПАСКАЛЬ. Руководство пользователя" 1989 - ничего такого не сказано. Полных описаний языка еще нигде не видел. Паскалей много всяких версий, у каждой свои детали.

Цитата
Это ты говоришь, что тебе ведом Паскалевский стиль? Если тебе так хочется думать - это твои проблемы. Вообще-то IOResult/DOSError + директива {$I} для отключения моментального вылета, как раз для того, чтобы можно было обработать ошибку - это все есть в паскале, начиная с 3-ей версии. На более старых просто не работал, возможно оно и там есть... Мало того, тебе даже предоставляются возможности (опять же, начиная как минимум с версии 5.5) искусственно создать ошибку, чтобы проверить, как твой код умеет её обрабатывать...
Конечно все это есть. Там и бестиповые указатели есть. Но это не классический ISO Pascal Standart.

Цитата
А ты говоришь - вылет. Вылет программы в некоторых местах равносилен вылету с работы, причем еще и с занесением в черный список. Будешь потом улицы мести, если возьмут...
Я программирую только для себя, в свободное время, ничего такого мне не грозит. Я только любитель.

Это всего лишь вопрос стиля. Не нужен вылет, упреждай ошибку проверками.
Некорректную программу обработка ошибок от вылета все равно не спасет, придется ее перезапускать. Некорректная программа может просто выдать ошибочный результат, который в тех же "некоторых местах" не менее опасен чем вылет. Вопрос надежности ПО.
Система не должна вылетать при вылете программы, она не работает в исполняемой среде программы. Для аппаратных ошибок (которые всегда постфактум) вопрос стиля это вообще чистый синтаксис: процедура не возвращает особое значение, а устанавливает флаг ошибки через параметр-переменную. Обработка аппаратных ошибок это всегда низкоуровневое (системное) средство, да и не все их можно обработать.
А система должна предоставлять программе высокого уровня ресурсы с детерминированным поведением: захватил ресурс, проверил его наличие - он должен безотказно работать, безо всяких перепроверок. Отказы нарушающие это правило должны приводить к вылету всякой высокоуровневой программы, если система их заметит (иначе она сама "рухнула" - не справилась со своими обязанностями).
Паскаль это стиль высокоуровневых программ.

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

Цитата
Хм. Ты работаешь на WinXP? Тебе не хватит допустимой вложенности папок (да, да, и у NTFS тоже есть ограничения), чтобы переполнить стек, в особенности, если пользуешься современным компилятором, таким, как FPC. В котором, кстати, размер стека можно и увеличить, если что...
С папками всякое может быть. Хочется иметь программу работающую в любых случаях, допустимых ОСью и ФС.
На моем компе стоит только FAT.

Цитата
А в Паскале ее и не должно быть. Должно быть обращение к функциям ОС для того, чтобы на этой ОС уже работать с ее функциями (насчет бестолковости или толковости - это ты сначала на свой код посмотри, а потом будешь WinAPI обсуждать). Если Турбо-Паскаль был написан в то время, когда кроме DOS ничего не было (а если и было - то TP там не запускался), то ничего кроме Uses DOS в языке и быть не должно. То, что ты запускаешь TP под Windows - это ни разу не проблема Паскаля. Это проблема твоя. Есть компиляторы под Windows - пользуйся ими, там прекрасно реализована работа с WinAPI. Или вообще кроссплатформенные версии - но за это будешь платить размером исполняемых файлов, в частности. Не веришь? Запусти Лазарус и откомпилируй приложение, показывающее форму с одной кнопкой. 12Мб EXE-шник тебе обеспечен. Дельфи (упс, это же только Windows, может поэтому размер EXE-шника меньше? Не надо заботиться о том, как этот же код должен компилироваться в другой ОС, не надо делать обертки разные?) тебе в таком случае уложится в 200К, а на чистом API можно и в 30К уложиться (но это еще ближе к ОСи, замечаешь?). Ты все еще хочешь универсальности, чтоб можно было из любой ОСи работать с функциями ОС однотипно?
Объем при кроссплатформенности зависит по крайней мере от числа реализуемых ОС и их версий. А если втупую утрамбовать компоненты бинарного кода оптимального под каждую из них + небольшой загрузчик, определяющий тип-версию ОС и передающий управление. 12Мб/30К = 400 ОСей и версий - зачем так много?

Универсальность исходного кода вполне совместима с чистым API. Перевод исходника в чистый API это работа компилятора, а не программиста. Системные примитивы в свою очередь должны позволять безопасную реализацию любого универсального кода без серьезной потери производительности по сравнению с эквивалентным машинным кодом или кодом на другой API. Иначе это никудышные примитивы.
С различными ФС в полной мере универсально работать нельзя, это разные типы данных.

Я API не изучал, да и не планирую. И программы с окнами не делал, не умею, и не собираюсь изучать. Это для меня запредельные материи. Освоить нереально.
Мне бы полноценную работу с ФС освоить, больше мне не надо. Задание (параметры) пишется в файл либо исходник, программа запускается, файлы читает, обрабатывает, создает, удаляет, и завершается, все результаты - файлах. Так я работаю. Примитивно, но доступно. Без поиска и перевода документации годами, жизнь то не резиновая.

Цитата
Вообще-то и отладчик и IDE идет в стандартной установке FPC, которая качается с официального сайта. Я уж не знаю, чего ты там качал, что у тебя отладчика не оказалось.
Я посмотрел, действительно есть, извиняюсь, не заметил. Но он такой же неадекватный как в BP7. И редактор (то есть IDE) такой же допотопный как BP7. Я поэтому редактирую в TMT, куда удобнее, там у меня получалось скомпилировать все написанные программки, кроме обсуждаемой здесь.

Цитата
И чем тебе FPC-шный FindFirst (из модуля SysUtils) - не расово верный? Работает и под ДОС, и под Windows, да и Unix-ы тоже не забывает. Я ж не виноват, что кое-кто не умеет читать доки, правда?
Доки пишутся невнятно. У меня были большие сомнения.
Что до идеологии: нет единообразия работы с каталогами и файлами. Чтобы отдельно дескриптор каталога с указателем, и отдельно буферная переменная со значением = запись файла в каталоге (имя, индекс или первый сектор). Каталоги не открываются, не закрываются, не захватываются (на запись/чтение) по сегментам имен файлов. Потом, через этот SearchRec нельзя сразу привязать дескриптор на файл. То есть файл я уже нашел, но получил только его имя, и теперь, получив путь к файлу, системе приходится заново проводить поиск, да еще начиная от корневого либо текущего во всех промежуточных каталогах, чтобы привязать дескриптор - крайне затратная операция (а как быть в Unix-е, где в одном каталоге несколько файлов могут иметь одно имя? хотя бы индекс файла нужно заполучить из SearchRec). То же самое из-за невозможности скопировать дескриптор. Вот это и есть бестолковая система примитивов.

Цитата
Пользоваться современными компиляторами, в них нет этого ограничения. Либо сторонними модулями (типа LDos) для старых компиляторов.
Что-то там подозрительно Windows 95 упоминается. А в какую папку распаковать, чтоб заработало?

Вот моя программа реализованная через рекурсию, компилироваться разумеется не будет.
Меньше не стала, появился дублирующий код. Кое-что исправлено.
Тело селективной функции упрощено до return(true). Закомментирована под завязку, чтобы никто голову не напрягал.
Код
{$I+, Q+, R+, S+}
program
  fullcopydir(
    dir1, dir2 : string; (* исходные директории, содержимое всех уровней вложенности которых, соответственно, селективно копируется и становится результатом селективного копирования *)
    prov : boolean (* необходимость проверки исходной директории dir1 и ее копии dir2 на вложенность *)
  );
const
  maxh = 127; (* предел глубины расположения файлов *)
  l = min(length(dir1), length(dir2)); (* вспомогательная константа, минимум длины абсолютного пути *)
var
  i : byte; (* вспомогательная переменная, номер символа абсолютного пути *)
  attr : word; (* атрибуты исходной директории dir1 *)
  time : longint; (* время ? исходной директории dir1 *)
  f, d : file; (* вспомогательные дескрипторы, соответственно, исходной директории dir1 и ее копии *)
  function
    sel(
      attr : byte; (* атрибуты проверяемого файла *)
      time : longint; (* время ? проверяемого файла *)
      size : longint; (* размер проверяемого файла *)
      name : string (* имя проверяемого файла *)
    ) : boolean; (* функция селекции на копирование проверяемого файла по некоторым полям его паспорта *)
  begin
    return(true)
  end;
  procedure
    copydir(
      h : [0..maxh]; (* глубина директории текущей dir1 и содержимых ею файлов *)
      b0 : boolean; (* выполнение текущей директорией dir1 условия селекции, т.е. ее затребованность для копирования *)
      ln : byte; (* максимальная длина абсолютного пути к содержимому текущей директории dir1 и к ее копии *)
      dir1, dir2 : string (* текущие директории, содержимое всех уровней вложенности которых, соответственно, селективно копируется и становится результатом селективного копирования *)
    );
  var
    e : boolean; (* условие успешного завершения текущего шага поиска *)
    i : byte; (* буферная переменная для копируемого байта *)
    f, g : file; (* вспомогательные дескрипторы, соответственно, копируемых и являющихся копиями файлов *)
    b : boolean; (* текущее значение условия сохранения копии директории dir1 *)
    sr : tsearchrec; (* паспорт найденных файлов и дескриптор поиска *)
  begin
    b := b0; (* начальное значение условия сохранения копии директории dir1 *)
    e := findfirst(dir1+'*', anyfile, sr)=0; (* поиск первого файла директории dir1, условие его нахождения *)
    while e do (* первый либо следующий файл директории dir1 найден *)
      if (sr.attr and directory)=directory then (* найденный файл - директория *)
        if (sr.name='.') or (sr.name='..') then (* найденный файл - специальная поддиректория, игнорируется *)
          e := findnext(sr)=0 (* поиск следующего файла директории dir1, условие его нахождения *)
        else (* найденный файл - обычная поддиректория *)
          begin (* копирование найденной поддиректории *)
            createdir(dir2+sr.name+'\'); (* создание пустой копии найденной поддиректории *)
            assign(g, dir2+sr.name+'\'); (* дескриптор копии найденной поддиректории *)
            setfattr(g, sr.attr); (* копирование атрибутов найденной поддиректории *)
            setftime(g, sr.time); (* копирование времени ? найденной поддиректории *)
            copydir(
              h+1, (* глубина найденной поддиректории и содержимых ею файлов *)
              sel(sr.attr, sr.time, sr.size, sr.name), (* выполнение условия селекции найденной поддиректорией, т.е. ее затребованность для копирования *)
              ln+length(sr.name)+1, (* максимум длины абсолютного пути к содержимому найденной поддиректории и ее копии *)
              dir1+sr.name+'\', (* найденная поддиректория *)
              dir2+sr.name+'\' (* копия найденной поддиректории *)
            ); (* селективное копирование содержимого всех уровней вложенности найденной поддиректории; удаление копии найденной поддиректории, если она пустая и не требуется *)
            e := findnext(sr)=0 (* поиск следующего файла директории dir1, условие его нахождения *)
          end
      else (* найденный файл - не директория *)
        begin
          if sel(sr.attr, sr.time, sr.size, sr.name) then (* найденный файл выполняет условию селекции, т.е. затребован для копирования *)
            begin  (* копирование найденного файла *)
              b := true; (* условие сохранения копии директории dir1 выполнено *)
              assign(f, dir1+sr.name); (* дескриптор найденного файла *)
              assign(g, dir2+sr.name); (* дескриптор копии найденного файла *)
              reset(f, 1); (* открытие найденного файла для побайтного чтения *)
              rewrite(g, 1); (* пересоздание и открытие копии найденного файла для побайтной записи *)
              (* копирование содержимого найденного файла *)
              while not eof(f) do (* конец найденного файла не достигнут *)
                begin
                  read(f, i); (* чтение текущего байта найденного файла *)
                  write(g, i) (* копирование текущего байта найденного файла *)
                end;
              close(f); (* закрытие найденного файла *)
              close(g); (* закрытие копии найденного файла *)
              setfattr(g, sr.attr) (* копирование атрибутов найденного файла *)
              setftime(g, sr.time); (* копирование времени ? найденного файла *)
            end;
          e := findnext(sr)=0 (* поиск следующего файла директории dir1, условие его нахождения *)
        end;
    (* первый либо следующий файл директории dir1 не найден *)
    findclose(sr); (* высвобождаем ресурсы поиска в директории dir1 *)
    (* проверка конечного условия сохранения копии директории dir1 = затребованность для копирования самой dir1 или некоторых содержимых ею файлов *)
    if not b then (* в директории dir2 нет скопированных файлов и сама она не требуется *)
      begin
        assign(g, dir2); (* дескриптор директории dir2 *)
        setfattr(g, $00); (* снятие флага 'только для чтения' с директории dir2 *)
        erase(g) (* удаление пустой директории dir2 *)
      end
  end;
begin
  if prov then (* необходима проверка исходной директории dir1 и ее копии *)
    begin
      (* проверка исходных директорий на вложенность *)
      i := 1;
      while i<=l and dir1[i]=dir2[i] do
        i := i+1;
      if i>l then (* исходные директории вложены *)
        halt (* аварийная остановка программы *)
    end;
  assign(f, dir1); (* дескриптор исходной директории dir1 *)
  getfattr(f, attr); (* чтение атрибутов исходной директории dir1 *)
  getftime(g, time); (* чтение времени ? исходной директории dir1 *)
  createdir(dir2); (* создание пустой копии исходной директории dir1 - директории dir2 *)
  assign(g, dir2); (* дескриптор директории dir2 *)
  setfattr(g, attr); (* копирование атрибутов исходной директории dir1 *)
  setftime(g, time); (* копирование времени ? исходной директории dir1 *)
  copydir(
    0, (* глубина исходной директории dir1 и содержимых ею файлов *)
    true, (* исходная директория dir1 требуется для копирования *)
    max(length(dir1),length(dir2)),
    dir1, (* исходная директория dir1 *)
    dir2 (* копия исходной директории dir1 *)
  ) (* селективное копирование содержимого всех уровней вложенности исходной директории dir1 *)
end.
Переменные h и ln можно выбросить, они задумывались для контроля, но так и не использованы.
CreateDir создает каталог, а если он уже существует, вызывает ошибку. А ReWrite затирает существующий файл, что несимметрично. Нельзя однако без обработки ошибок создать файл, вызывая ошибку если он уже существует.
Программа во время работы не только создает, но и удаляет ненужные каталоги. При рекурсии это исправить затруднительно.

Компиляция на FPC выдает ту же ошибку в четвертой строке:
dir1, dir2 : string;
пишет:
dir1.pas(4,16) Fatal: Syntax Error, ")" expected but ":" fond
dir1.pas(0) Fatal: Compilation aborted
запись параметров в одну строку не помогает.
Вот что ему не нравится? типизация через двоеточие? причем здесь закрывающая скобка?
Похоже отладчик не однопроходный, ошибки ищет не последовательно.
Я должен по всему документу рыскать, где там синтаксис нарушен? - в ж... такой отладчик!


--------------------
взять бы всех программистов - да утопить
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Профи
****

Группа: Пользователи
Сообщений: 865
Пол: Мужской
Реальное имя: Вячеслав

Репутация: -  20  +


program  fullcopydir(
...
а указать имя программы?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Гость






Цитата
Меньше не стала, появился дублирующий код
Если ты пишешь так, что у тебя получается результирующий код - это что, означает, что так надо писать? Отнюдь, это означает, что у тебя просто не получается писать не на Maple, вот и все.

Цитата
Что-то там подозрительно Windows 95 упоминается. А в какую папку распаковать, чтоб заработало?
Имеется в виду, что ДО Win95 оно работать не будет - Win 3.х еще не поддерживали длинные имена файлов, если что... Распаковать в ту же папку, где лежит твой проект, и подключить в списке Uses...

Цитата
компилироваться разумеется не будет.
Разумеется, я ж сказал: в заголовке процедуры нельзя описывать типы, а что делаешь ты?

Цитата
  procedure
copydir(
h : [0..maxh]; (* глубина директории текущей dir1 и содержимых ею файлов *)
b0 : boolean; (* выполнение текущей директорией dir1 условия селекции, т.е. ее затребованность для копирования *)
ln : byte; (* максимальная длина абсолютного пути к содержимому текущей директории dir1 и к ее копии *)
dir1, dir2 : string (* текущие директории, содержимое всех уровней вложенности которых, соответственно, селективно копируется и становится результатом селективного копирования *)
);

И что за параметр H, как не попытка описать новый тип прямо на месте? Опиши заранее, потом используй...

Попробую твой код привести к нормальному виду, чтоб без дублирования, вот тогда посмотрим, увеличился его объем из-за рекурсии, или наоборот...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


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

Зачем тебе общий случай? Универсальных вещей не существует.

> Турбо Паскаль не вполне Паскаль.

Ты на каком пишешь?

> Иначе, зачем Eof если есть IOResult ?

Для удобства.

> Отладчик это компенсация плохого хелпа.

ЛОЛШТО

> Не кристально ясный, неполный, не родного языка хелп - это не хелп.

Транслате.гугл.ру

> Что толку в длинных строках, сомневаюсь что сами файловые процедуры Assign, FindFirst с ними работают.

А ты проверял, чтобы сомневаться? Проверь. В дельфе именно с ними они и работают.

> Не знаю как с этим в Дельфи, но это еще более громоздкая, более сложная для изучения вещь, чем BP и FPC.

И в ФПЦ тоже строки длинные. Вот блин, и жаловаться-то некуда, куда ни плюсь - нигде нет проблем, всё решено, шо робыть, шо робыть...


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Код

{$I+, Q+, R+, S+}
program
  fullcopydir(
    dir1, dir2 : string;
    prov : boolean;
  );                                        {ЩО ЦЕ?!}
const
  maxh = 127;
  l = min(length(dir1), length(dir2));    {ЩО ЦЕ?!}
var
  i : byte;
  attr : word;
  time : longint;
  f, d : file;
  function
    sel(
      attr : byte;
      time : longint;
      name : string;
    ) : boolean;
  begin
    return(true)              {ЩО ЦЕ?! Тяжёлое наследие Си?}
  end;
  procedure
    copydir(
      h : [0..maxh];                {ЩО ЦЕ?!}
      b0 : boolean;
      ln : byte;
      dir1, dir2 : string


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Гость






В общем, так, ddn...

Вот этот код (Показать/Скрыть)

прекрасно компилируется FPC (2.4.0, Target = Win32) и работает, копирует по твоему алгоритму папки с подпапками и файлами из одного места в другое. Но... В нем есть ошибка. Логическая. Исправлять её - тебе (я строки, ее содержащие, закомментировал).

Вот там, где ты проверяешь, что в папку не было скопировано ни одного файла, и в зависимости от результата проверки B так сразу легко и просто удаляешь директорию, которая по твоему мнению - пустая (на данном уровне рекурсии файлы в нее не копировались). А что будет, если в ее дочернюю директорию копировались файлы (да и вообще, если текущая папка содержит подпапки), и ты попытаешься такую папку удалить через Erase? Кто вообще удаляет папки через Erase? Для этого придумали RD (оно же - RmDir).

Здесь надо действовать по-другому. Попробуй догадаться, как...
Цитата
При рекурсии это исправить затруднительно
Неправда. При рекурсии это исправить проще простого. По крайней мере, гораздо проще, чем при итерации...

P.S. На всякий случай - копировать файлы побайтно - долгая история. В Хелпе Турбо Паскаля лежит пример использования BlockRead, так вот там приведена программа, производящее гораздо более быстрое копирование файла.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


До меня дошло.

Код

program
  fullcopydir(
    dir1, dir2 : string;
    prov : boolean;
  );    


Тут имелся в виду аналог сишного int main(char** args)
Даже если бы такая ктнструкция была в языке, как ты собрался на этапе _компиляции_ вычислять

Код

const
  l = min(length(dir1), length(dir2));
?!

То, что стоит в конст - это то, что должен вычислить компилятор. Откуда ему знать длину параметров, с которыми программу буду запускать?

Кстати, для получения параметров командной строки надо вызывать функцию ParamStr(i). ParamStr(0) возвращает полное имя екзешника, с путём. ParamCount возвращает количество параметров.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Гость






Цитата
Цитата
program fullcopydir(
...
а указать имя программы?
fullcopydir и есть ее имя.

Цитата
Разумеется, я ж сказал: в заголовке процедуры нельзя описывать типы, а что делаешь ты?
И что за параметр H, как не попытка описать новый тип прямо на месте? Опиши заранее, потом используй...
Понял.
Я то подумал про параметр функционального типа.

Значит программы не могут иметь параметров. Придется задавать их в виде констант.

Цитата
Зачем тебе общий случай? Универсальных вещей не существует.
Речь не об этой программе, в других программах может понадобиться глубокая рекурсия.

Цитата
> Иначе, зачем Eof если есть IOResult ?

Для удобства.
А у меня идиосинкразия. Опять же вопрос стиля.


Цитата
> Отладчик это компенсация плохого хелпа.

ЛОЛШТО
Отладчик показывает где и в чем нарушен синтаксис и смысл конструкций языка. Можно угадать правила языка, даже если хелпа нет.

Цитата
> Не кристально ясный, неполный, не родного языка хелп - это не хелп.

Транслате.гугл.ру
Пользуюсь Транслате, перевод неважнецкий.
Но если хелп скупой на объяснения, да еще и неполный более чем на половину.

На Дельфи пока рано переходить, весит больше, багов больше.

Цитата
Код
  l = min(length(dir1), length(dir2));    {ЩО ЦЕ?!}
Константное выражение, что нельзя?
Ладно, сделаем переменной.

Цитата
Код
    return(true)              {ЩО ЦЕ?! Тяжёлое наследие Си?}
Это заглушка.
Вместо нее вставить нужный код.

Цитата
Код
      h : [0..maxh];                {ЩО ЦЕ?!}
Выражение для типа. Да, уже говорилось, исправим.

Исправленный код
Код
{$I+, Q+, R+, S+}
program fullcopydir;
const
  dir1 = 'вставить нужный путь'; (* исходная директория, содержимое всех уровней вложенности которой селективно копируется *)
  dir2 = 'вставить нужный путь'; (* исходная директория, содержимое всех уровней вложенности которой становится результатом селективного копирования *)
  prov = true; (* необходимость проверки исходной директории dir1 и ее копии dir2 на вложенность *)
  maxh = 127; (* предел глубины расположения файлов *)
type
  dh = [0..maxh]; (*диапазон глубины директорий *)
var
  i, l : byte; (* вспомогательные переменные, соответсвенно, номер символа абсолютного пути и минимум длины абсолютного пути *)
  attr : word; (* атрибуты исходной директории dir1 *)
  time : longint; (* время ? исходной директории dir1 *)
  f, d : file; (* вспомогательные дескрипторы, соответственно, исходной директории dir1 и ее копии *)
  function
    sel(
      attr : byte; (* атрибуты проверяемого файла *)
      time : longint; (* время ? проверяемого файла *)
      size : longint; (* размер проверяемого файла *)
      name : string (* имя проверяемого файла *)
    ) : boolean; (* функция селекции на копирование проверяемого файла по некоторым полям его паспорта *)
  begin
    return(true)
  end;
  procedure
    copydir(
      h : dh; (* глубина директории текущей dir1 и содержимых ею файлов *)
      b0 : boolean; (* выполнение текущей директорией dir1 условия селекции, т.е. ее затребованность для копирования *)
      ln : byte; (* максимальная длина абсолютного пути к содержимому текущей директории dir1 и к ее копии *)
      dir1, dir2 : string (* текущие директории, содержимое всех уровней вложенности которых, соответственно, селективно копируется и становится результатом селективного копирования *)
    );
  var
    e : boolean; (* условие успешного завершения текущего шага поиска *)
    i : byte; (* буферная переменная для копируемого байта *)
    f, g : file; (* вспомогательные дескрипторы, соответственно, копируемых и являющихся копиями файлов *)
    b : boolean; (* текущее значение условия сохранения копии директории dir1 *)
    sr : tsearchrec; (* паспорт найденных файлов и дескриптор поиска *)
  begin
    b := b0; (* начальное значение условия сохранения копии директории dir1 *)
    e := findfirst(dir1+'*', anyfile, sr)=0; (* поиск первого файла директории dir1, условие его нахождения *)
    while e do (* первый либо следующий файл директории dir1 найден *)
      if (sr.attr and directory)=directory then (* найденный файл - директория *)
        if (sr.name='.') or (sr.name='..') then (* найденный файл - специальная поддиректория, игнорируется *)
          e := findnext(sr)=0 (* поиск следующего файла директории dir1, условие его нахождения *)
        else (* найденный файл - обычная поддиректория *)
          begin (* копирование найденной поддиректории *)
            createdir(dir2+sr.name+'\'); (* создание пустой копии найденной поддиректории *)
            assign(g, dir2+sr.name+'\'); (* дескриптор копии найденной поддиректории *)
            setfattr(g, sr.attr); (* копирование атрибутов найденной поддиректории *)
            setftime(g, sr.time); (* копирование времени ? найденной поддиректории *)
            copydir(
              h+1, (* глубина найденной поддиректории и содержимых ею файлов *)
              sel(sr.attr, sr.time, sr.size, sr.name), (* выполнение условия селекции найденной поддиректорией, т.е. ее затребованность для копирования *)
              ln+length(sr.name)+1, (* максимум длины абсолютного пути к содержимому найденной поддиректории и ее копии *)
              dir1+sr.name+'\', (* найденная поддиректория *)
              dir2+sr.name+'\' (* копия найденной поддиректории *)
            ); (* селективное копирование содержимого всех уровней вложенности найденной поддиректории; удаление копии найденной поддиректории, если она пустая и не требуется *)
            e := findnext(sr)=0 (* поиск следующего файла директории dir1, условие его нахождения *)
          end
      else (* найденный файл - не директория *)
        begin
          if sel(sr.attr, sr.time, sr.size, sr.name) then (* найденный файл выполняет условию селекции, т.е. затребован для копирования *)
            begin  (* копирование найденного файла *)
              b := true; (* условие сохранения копии директории dir1 выполнено *)
              assign(f, dir1+sr.name); (* дескриптор найденного файла *)
              assign(g, dir2+sr.name); (* дескриптор копии найденного файла *)
              reset(f, 1); (* открытие найденного файла для побайтного чтения *)
              rewrite(g, 1); (* пересоздание и открытие копии найденного файла для побайтной записи *)
              (* копирование содержимого найденного файла *)
              while not eof(f) do (* конец найденного файла не достигнут *)
                begin
                  read(f, i); (* чтение текущего байта найденного файла *)
                  write(g, i) (* копирование текущего байта найденного файла *)
                end;
              close(f); (* закрытие найденного файла *)
              close(g); (* закрытие копии найденного файла *)
              setfattr(g, sr.attr); (* копирование атрибутов найденного файла *)
              setftime(g, sr.time) (* копирование времени ? найденного файла *)
            end;
          e := findnext(sr)=0 (* поиск следующего файла директории dir1, условие его нахождения *)
        end;
    (* первый либо следующий файл директории dir1 не найден *)
    findclose(sr); (* высвобождаем ресурсы поиска в директории dir1 *)
    (* проверка конечного условия сохранения копии директории dir1 = затребованность для копирования самой dir1 или некоторых содержимых ею файлов *)
    if not b then (* в директории dir2 нет скопированных файлов и сама она не требуется *)
      begin
        assign(g, dir2); (* дескриптор директории dir2 *)
        setfattr(g, $00); (* снятие флага 'только для чтения' с директории dir2 *)
        erase(g) (* удаление пустой директории dir2 *)
      end
  end;
begin
  if prov then (* необходима проверка исходной директории dir1 и ее копии *)
    begin
      (* проверка исходных директорий на вложенность *)
      i := 1;
      l := min(length(dir1), length(dir2));
      while i<=l and dir1[i]=dir2[i] do
        i := i+1;
      if i>l then (* исходные директории вложены *)
        halt (* аварийная остановка программы *)
    end;
  assign(f, dir1); (* дескриптор исходной директории dir1 *)
  getfattr(f, attr); (* чтение атрибутов исходной директории dir1 *)
  getftime(g, time); (* чтение времени ? исходной директории dir1 *)
  createdir(dir2); (* создание пустой копии исходной директории dir1 - директории dir2 *)
  assign(g, dir2); (* дескриптор директории dir2 *)
  setfattr(g, attr); (* копирование атрибутов исходной директории dir1 *)
  setftime(g, time); (* копирование времени ? исходной директории dir1 *)
  copydir(
    0, (* глубина исходной директории dir1 и содержимых ею файлов *)
    true, (* исходная директория dir1 требуется для копирования *)
    max(length(dir1),length(dir2)),
    dir1, (* исходная директория dir1 *)
    dir2 (* копия исходной директории dir1 *)
  ) (* селективное копирование содержимого всех уровней вложенности исходной директории dir1 *)
end.
Теперь отладчик пишет просто:
Fatal: Compilation aborted

volvo, ваше последнее сообщение еще не просмотрел.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Гость






Цитата
fullcopydir и есть ее имя.
В таком случае ЭТО - не Паскаль. По крайней мере, компиляторов, способных откомпилировать твой код, на данный момент не существует. Программа и подпрограмма (которая может принимать параметры) - это разные вещи. Учи язык, если хочешь с ним работать.

Цитата
Это заглушка.
Заглушка тоже должна компилироваться. Это компилироваться не будет. Ибо слова Return в Паскале нет.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> На Дельфи пока рано переходить, весит больше, багов больше.

Да, семёрка в архиве 100 Мб. Но проблемы тут не вижу. Загружается она у меня не то, чтобы быстро, но терпимо, секунд 5. Да, я ставил минимальную версию (только добавил к ней помощь, исходники и редактор иконок).
Единственный баг в ней - это иногда пропадает ввод пробелов и всяких символов, тогда надо перезапускать. Случается это у меня в среднем раз в неделю.
В Паскале же бывают баги с неверным вычислением выражения, бывает, что ни с того ни с сего инвалид флоатинг поинт оператион (я уже знаю, что это стек сопроцессора переполняется, надо выражение в несколько этапов считать), а ещё из-за бесконтрольного доступа чего угодно к чему угодно баги в программе могут привести к каким угодно последствиям.

> Константное выражение, что нельзя?

Оно не константа, потому что оно не известно на этапе компиляции.

Сообщение отредактировано: TarasBer -


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #20





Группа: Пользователи
Сообщений: 6
Пол: Мужской

Репутация: -  0  +


Вот блин, под гостем оставил.
Там нужно исправить
f, d : file;
d заменить на g, постоянно всплывает этот старый идентификатор.
А еще диапазонный тип сделать без квадратных скобок.
Но отладчик выдает то же.

volvo, пару замечаний по вашей программе.
type идет после var, разве можно?
Там есть обработка исключений try finally, с ней никогда не работал.
Я так понял она просто делает переход на finally (раз except нет), если внутри блока возникла ошибка.
continue - фи, неструктурно!
e : boolean выбросить, в create_folder(dir2+sr.name+'\', sr.attr, sr.time) проставить dir_to_be_created.
Почему-то запуск fullcopydir('F:\T\', 'F:\G\', true) вне модуля program.

Цитата('volvo')
Вот там, где ты проверяешь, что в папку не было скопировано ни одного файла, и в зависимости от результата проверки B так сразу легко и просто удаляешь директорию, которая по твоему мнению - пустая (на данном уровне рекурсии файлы в нее не копировались). А что будет, если в ее дочернюю директорию копировались файлы (да и вообще, если текущая папка содержит подпапки), и ты попытаешься такую папку удалить через Erase? Кто вообще удаляет папки через Erase? Для этого придумали RD (оно же - RmDir).
Да, я и забыл про подкаталоги! Если обычный подкаталог найден, скопирован с содержимым и копия его не удалена, то после нужно поставить флаг b:=true. Придется сделать параметр-переменную и через нее передавать, что копия подкаталога не стерта.

Цитата('volvo')
Здесь надо действовать по-другому. Попробуй догадаться, как...
Нет, как раз не надо. Если в копии каталога есть скопированные подкаталоги, его удалять не надо - так и задумано.
Функция селекции одинаково проверяет и файлы, и каталоги (по атрибутам можно определить), каждый независимо от остальных. Любой каталог dir1, который даже не затребован селекцией, все равно копируется. Когда копирование его содержимого завершено, если в содержимом копии dir2 этого каталога есть файлы или каталоги (любого уровня вложенности), то и копия dir2 этого каталога не удаляется, даже если она сама отдельно не затребована (иначе куда девать содержимое этой копии). Только пустая копия должна удаляться, если она сама не требуется.

Цитата('volvo')
Неправда. При рекурсии это исправить проще простого. По крайней мере, гораздо проще, чем при итерации...
Проблема (незнаю, насколько она серьезна) в том, чтобы не создавать копий тех каталогов, которые в конце своей обработки останутся пустыми и будут удалены. Здесь нужно запоминать все промежуточные каталоги и создать их лишь в том момент, когда на некотором уровне вложенности появился затребованный селекцией файл или каталог.

Цитата('volvo')
P.S. На всякий случай - копировать файлы побайтно - долгая история. В Хелпе Турбо Паскаля лежит пример использования BlockRead, так вот там приведена программа, производящее гораздо более быстрое копирование файла.
Зачем SizeOf(Buf) вычисляется каждый раз, разве размер памяти под значение Buf меняется?

Цитата('TarasBer')
То, что стоит в конст - это то, что должен вычислить компилятор. Откуда ему знать длину параметров, с которыми программу буду запускать?
Да, верно.

Цитата('volvo')
В таком случае ЭТО - не Паскаль. По крайней мере, компиляторов, способных откомпилировать твой код, на данный момент не существует. Программа и подпрограмма (которая может принимать параметры) - это разные вещи. Учи язык, если хочешь с ним работать.
Сначала fullcopydir и была процедурой, потом, чтобы сделать ее работающей переделал в программу. Ведь procedure только декларирует, а исполняется только то, что в теле program. А про параметры я и не подумал.

Цитата('volvo')
Заглушка тоже должна компилироваться. Это компилироваться не будет. Ибо слова Return в Паскале нет.
Да, Return это в Модуле-2, и в Мапле.

Цитата('TarasBer')
Да, семёрка в архиве 100 Мб. Но проблемы тут не вижу.
На моем диске напряженка со свободным местом. А второй винт БП не тянет.

Цитата('TarasBer')
Единственный баг в ней - это иногда пропадает ввод пробелов и всяких символов, тогда надо перезапускать. Случается это у меня в среднем раз в неделю.
В Паскале же бывают баги ... из-за бесконтрольного доступа чего угодно к чему угодно баги в программе могут привести к каким угодно последствиям.
В то, что компилятор Дельфи (а не среда разработки) без багов как-то не вериться.
А в Дельфи доступ к чему угодно чем-то ограничен?

volvo, вашу он прокомпилировал - 134666 b.
В своей процедуре поставил {$mode delphi} {$I+, Q+, R+, S+} uses dos, sysutils, math после program;
заменил read(f, i) и write(g, i) на blockread(f, i, 1) и blockwrite(g, i, 1);
return(true) на sel := true;
поставил скобки в (i<=l) and (dir1[i]=dir2[i]),
и у меня тоже компилировал, наконец-то - 134494 b.


--------------------
взять бы всех программистов - да утопить
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

2 страниц V  1 2 >
 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 29.03.2024 22:45
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name