На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
    > Фортран. Просмотр содержимого диска
      Знатоки Фортрана!

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

      заранее спасибо!
        Нету у Фортрана таких функций.
        Нужно пользоваться функциями ОС, например, WinAPI.
          andriano!

          Я не слишком искушен в программировании.
          Честно говоря, когда ты говоришь об использовании функций WinAPI, я совсем не
          понимаю о чем идет речь...
          Можешь дать конкретный совет - как мне решить эту проблему?

          Добавлено
          Пока искал, наткнулся на реализацию процесса просмотра структуры директории
          с помощью FindFirstFile и FindNextFile на Си.
          Нет ли аналогичных функций в Фортране?

          Мне просто не верится, что НИКТО и НИКОГДА не
          пытался решить аналогичную проблему на Фортране...
            Ну, фортран как бы обычно используется для несколько других целей (научно-технические расчеты). И в эти цели как-то не входит сканирование директорий.

            Фортран даже со строками-то нормально работать не умеет. Тебе придется вручную все реализовывать.
              Парадокс в том, что именно для научных целей я его и использую... Я - радиофизик-экспериментатор.
              На основе экспериментальных данных решается обратная задача восстановления
              некоторых параметров процесса.
              Данные поступают постоянно и сохраняются в виде файлов. И это первая "точка доступа", где
              необходимо сканирование - для отслеживания поступления новых данных.
              Далее решается непосредственно задача.
              В ходе ее решения образуется большое количество одноименных файлов, раскидывающихся по различным папкам
              воизбежании путанницы.
              Для финальной обработки требуется перелопатить все эти директории...
              Программы решения задачи писал сам. Вручную отбирал нужные файлы и решения...
              Теперь, вроде как, все отлажено и надо автоматизировать...

              Видимо придется писать головную программу на СИ, а все фортрановские программы
              реализовывать в виде функций... Но так не хочется мешать языки...
                Можешь написать подпрограмму(ы) на C, которая будет сканировать директорию, и вызывать ее(их) из своих фортрановских программ. Так пожалуй будет гораздо проще. К тому же, подозреваю, C-ная библиотека и так в качестве подстилающей в фортрановской используется (ты не написал, каким именно компилятором фортрана пользуешься). Так что программа в результате даже не увеличится заметно.

                Добавлено
                Вводя имя файла с клавиатуры у тебя получается его открывать?
                  To AMK!

                  Спасибо за совет и участие!

                  Пользуюсь, по-старинке, Compaq Visual Fortran 6.1.

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

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

                  Кстати, вот, нарыл на буржуинских сайтах два варианта получения структуры каталогов.
                  Пока не дошли руки их опробовать.
                  Хочу узнать мнение компитентных программистов - это сработает?

                  Первый:

                  CHARACTER(10) :: extension="f90"
                  CHARACTER(255) :: cfile

                  IF(os == "unix") THEN
                  CALL system('ls -1 -p *.'//TRIM(extension)//'> list')
                  ELSE
                  CALL system('dir /b/ad/on *.'//TRIM(extension)//'> list')
                  ENDIF

                  Notice the options used respectively for the os dependent commands
                  "ls" and "dir" : they provide a very similar result ! After that, you
                  just have to open the file "list" and read each line using the format
                  "(A)" :

                  OPEN(15,file="list") ! of course you can use another unit or even
                  select a free unit
                  ! or even select a free unit (not used) but this
                  is another story
                  n=0
                  DO
                  READ(15,"(A)",END=10) cfile
                  write(*,*) TRIM(cfile)
                  ENDDO
                  10 CONTINUE

                  Small note: the option /ad means select only directories

                  Or for those compilers where SYSTEM is a function not a subroutine
                  ivalue = system( ... )

                  Right ... a bug again ! I copied an example dedicated to get sub-
                  directories only. Sorry


                  И второй:


                  There are many ways to solve this problem, including WINAPI calls but the
                  simplest (least sophistocated) would be to construct a subroutine to get
                  the list of all files in the tree, using a system call. Then open the log
                  file, say "dir.log", parse the file to generate a list of files you may
                  want, noteing the directory and file names, then close and delete the
                  temporary log file. You can then search the in memory list of files you
                  generated, when required. You need to make sure that your parser can cope
                  with the variety of directory listings that various Winxx operating systems
                  can provide, or at least the ones you use. It is possible !! Use of VER
                  could help. Also, make sure long names are available and not just 8.3
                  format.

                  call system ('ver >dir.log')
                  call system ('dir c:work*.dat /s >>dir.log')
                  open (unit=91, file='dir.log')
                  !
                  call parse_this_file_list
                  !
                  close (unit=91, ststus='DELETE')

                  Ising Wisk may provide better solutions, but for a simple dos interface,
                  this is a reliable solution.
                    Цитата IlyaNikSad @
                    Пока искал, наткнулся на реализацию процесса просмотра структуры директории
                    с помощью FindFirstFile и FindNextFile на Си.
                    Нет ли аналогичных функций в Фортране?

                    Мне просто не верится, что НИКТО и НИКОГДА не
                    пытался решить аналогичную проблему на Фортране...

                    Ты будешь удивлен, но в С _ТОЖЕ_ нет функций работы с файловой системой.
                    А упомянутые тобой FindFirstFile и FindNextFile - и есть те самые функции WinAPI. Вызывать их можно из _ЛЮБОГО_ языка: Си, Фортрана, Паскаля, Ассемблера, etc.
                    Т.е. тебе нужно просто переписать нужный тебе фрагмент с С на Фортран.
                    Естественно, там, где вызываются процедуры (не возвращающие значения), нужно использовать оператор call.
                    И еще нужно либо ручками прописать прототипы используемых функций (делать это ручками, честно говоря, большая экзотика - но такой способ есть), либо подключить нужный заголовочный модуль оператором use в начале программной единицы, которая будет использовать эти функции.
                    Нужный файл находится поиском по содержимому "FindFirstFile" в директории, куда установлен компилятор и библиотеки Фортрана. Навскидку имя конкретного файла не помню (возможно, kernel32), а дома Фортрана не держу.
                    В принципе, попытайся вставить перед строкой "IMPLICIT NONE" строку "Use kernel32". Если не поможет, тогда уже прибегай к поиску.

                    Вариант с
                    CALL system('dir /b/ad/on *.'//TRIM(extension)//'> list')
                    по сути готовит для тебя файл "list", в котором в текстовом виде содержится структура директорий так, как она выдается командой ОС dir.
                    Можно считать этот файл и распарсить.
                    Но, надо сказать, Фортран - не лучший инструмент для парсинга текста. Так что я бы все-таки порекомендовал вариант с переписывание с Си на Фортран.
                    Подключение функции, написанной на Си, тоже возможно, тем более в VC, которая используется как оболочка для Compaq Fortran, вроде, с этим проблем быть не должно, но IMHO переписать на знакомом языке полтора десятка строк - проще.

                    Да, еще вспомнил:
                    Фортран - по умолчанию язык нерекурсивный, а просмотр директорий обычно реализуется рекурсивным алгоритмом, поэтому где-то там нужно явно указать, что используемая функция рекурсивная.
                    Сообщение отредактировано: andriano -
                      To Andriano!

                      Спасибо за советы и реккомендации!
                      Честно говоря, ХОРОШИЙ вариант написанной мной программы требует
                      правильной реализации - правильной реализации всех функций, процедур и т.д. ...
                      Я давно об этом думаю...
                      Просто объем программ, написанных мной на корявом Фортране (однако, работающих безупречно), просто ужасает...
                      Я просто боюсь за это взяться... Но если возьмусь, то, вероятно, самым правильным будет
                      (как вы и говорили) потратить немного времени и написать часть программ на СИ...

                      В любом случае, попробую (дурацкая упрямость) написать вариант на Фортране.
                      Потом, вероятно, дойду и до Си.

                      Спасибо за советы ВСЕМ!
                      Будут идеи, или кто-то встретит хорошую реализацию упомянутой мной проблемы - пишите!
                      Со своей стороны, постараюсь отписать по результатам своих изысканий, вдруг
                      кому пригодится...

                      Спасибо, и удачи!
                        Если программу на корявом фортране аккуратно переписать, то фортран может оказаться и не корявым вовсе

                        А в Compaq Visual Fortran 6.1 действительно используется библиотека VC++ версии кажется 6, соответственно доступны и все функции C (некоторые используются в качестве процедур). Одни вызываются прямо, для других уже в библиотеке самого фортрана есть адаптер, согласующий правила вызова.
                        Если не ошибаюсь, CVF6.1 реализует стандарты вплоть до FORTRAN-90 (этот возможно черновой), то есть позволяет описывать прототипы функций и процедур. К сожалению у меня его под рукой тоже нет, посмотреть сам и написать подробнее не могу (да и ошибиться где-то мог).
                          to amk!

                          amk, когда я писал фразу "объем программ, написанных мной на корявом Фортране (однако, работающих безупречно)"
                          я не имел ввиду, что язык Фортран корявый. Это моё неумение писать правильно на Фортране сделали мои программы
                          корявыми.

                          Приношу извинения, если эта фраза задела кого-либо...
                            Самое корявое, на мой взгляд в фортране - это возможность использовать переменные и процедуры без предварительного явного их описания. Полвека назад это может и имело смысл, но не сейчас
                              Цитата IlyaNikSad @
                              to amk!

                              amk, когда я писал фразу "объем программ, написанных мной на корявом Фортране (однако, работающих безупречно)"
                              я не имел ввиду, что язык Фортран корявый. Это моё неумение писать правильно на Фортране сделали мои программы
                              корявыми.

                              Приношу извинения, если эта фраза задела кого-либо...

                              Вообще-то Фортран - язык специализированный. Т.е. имеющий вполне конкретную и ограниченную область применения.
                              Он очень удобен для написания вычислительных программ, но обработка текста, графики, пользовательский интерфейс и т.п. на нем достаточно геморройны.
                              Хотя и сам иногда пишу на Фортране и графику (визуализация результатов научных расчетов) и пользовательский интерфейс (для тех же научных расчетов) ну и минимум обработки текста (для генерации осмысленных имен файлов и обхода ошибок в системных функциях, например, в операторе write).
                              А лет 20 назад не удержался и от увлечения писать на Фортране игры. :)
                              Но тогда к нему приходилось довольно много дописывать на Ассемблере.

                              Добавлено
                              Цитата amk @
                              Самое корявое, на мой взгляд в фортране - это возможность использовать переменные и процедуры без предварительного явного их описания. Полвека назад это может и имело смысл, но не сейчас

                              Ну, слава Богу, этот очень серьезный недостаток пользователь волен отключить оператором IMPLICIT NONE.
                                Волен отключить, но волен и не отключать. И многие именно возможностью не отключать и пользуются. В результате получается иногда огромная программа, в которой нет ни одного слова ни об одной из переменных.
                                  Цитата amk @
                                  1. Волен отключить, но волен и не отключать. И многие именно возможностью не отключать и пользуются.
                                  2. В результате получается иногда огромная программа, в которой нет ни одного слова ни об одной из переменных.

                                  1. Это неправильные программисты.
                                  2. Огромную программу таким методом написать невозможно. А большую - очень трудно.

                                  Добавлено
                                  На скорую руку слепил что-то.
                                  В процессе в очередной раз убедился, что Фортран не подходит для обработки текста.
                                  ExpandedWrap disabled
                                    module FindFilesModule
                                    integer NumFiles ! счетчик файлов
                                    integer NumDirs  ! счетчик директорий
                                    end module FindFilesModule
                                     
                                    subroutine ConvertCstring2For(s)
                                    implicit none
                                    character*260 s
                                    integer i,j
                                      j = 0
                                      do i = 1, 260
                                        if (s(i:i) .lt. ' ') j = 1
                                        if(j .eq. 1)s(i:i) = ' '
                                      enddo
                                    end
                                     
                                    recursive subroutine AllFileFindNext(CurrPath) ! {ищет все файлы по пути и всем поддиректориям}
                                    use kernel32
                                    use FindFilesModule
                                    implicit none
                                    TYPE (T_WIN32_FIND_DATA) sr
                                    character*MAX_PATH s, CurrPath
                                    integer h,j,L
                                    logical*1 b
                                      L = len_trim(CurrPath)
                                      if ( CurrPath(L:L) .ne. '\') CurrPath = trim(CurrPath)//'\'
                                      s = trim(CurrPath)//'*.*'C
                                      h = FindFirstFile(s, sr)
                                      do while (h .ne. 0)
                                        call ConvertCstring2For(sr.cFileName)
                                        if ((trim(sr.cFileName) .ne. '.') .and. (trim(sr.cFileName) .ne. '..')) then
                                          if (iand(sr.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY) .eq. FILE_ATTRIBUTE_DIRECTORY) then
                                            NumDirs = NumDirs + 1
                                            s = trim(CurrPath)//trim(sr.cFileName)//'\'
                                            write(*,*)'DIR: [',trim(s),']'
                                            call AllFileFindNext(s)
                                          end if
                                        end if
                                        b = FindNextFile(h,sr)
                                        if(.not. b)then
                                          call FindClose(h)
                                          h = 0
                                        endif
                                      end do
                                      s = trim(CurrPath)//'*.*'C
                                      h = FindFirstFile(s, sr)
                                      do while (h .ne. 0)
                                        call ConvertCstring2For(sr.cFileName)
                                        if ((trim(sr.cFileName) .ne. '.') .and. (trim(sr.cFileName) .ne. '..') .and. (iand(sr.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY) .ne. FILE_ATTRIBUTE_DIRECTORY)) then
                                          NumFiles = NumFiles + 1
                                          write(*,*)'FILE:['//trim(CurrPath)//trim(sr.cFileName)//']'
                                        end if
                                        b = FindNextFile(h,sr)
                                        if(.not. b)then
                                          call FindClose(h)
                                          h = 0
                                        endif
                                      end do
                                    end;
                                     
                                    subroutine AllFileFind(path) ! {ищет все файлы по пути и всем}
                                    use kernel32
                                    use FindFilesModule
                                    implicit none
                                    integer i
                                    character*MAX_PATH path
                                      write(*,*)'1 AllFileFind ['//trim(path)//'] ',len_trim(path)
                                      NumFiles = 0
                                      NumDirs = 0
                                      i = len_trim(Path)
                                      if ( Path(i:i) .ne. '\') Path = trim(Path)//'\'
                                      write(*,*)'2 AllFileFind ['//trim(path)//'] ',len_trim(path)
                                      call AllFileFindNext(path)
                                      write(*,*)'Found ',NumFiles,' files, ',NumDirs,' dir-s'
                                    end
                                     
                                    program FndFrstNxt
                                    use kernel32
                                    implicit none
                                    character*MAX_PATH s
                                    integer i
                                      call GetCurrentDirectory(260, s)
                                      call ConvertCstring2For(s)
                                      call AllFileFind(s)
                                    end program FndFrstNxt
                                    Цитата andriano @
                                    1. Это неправильные программисты.
                                    Исторически так повелось, что большая часть программирующих на фортране вообще не программисты.
                                    Цитата andriano @
                                    2. Огромную программу таким методом написать невозможно. А большую - очень трудно.
                                    При должной настойчивости все возможно. Вдобавок, при полном отсутствии комментариев, даже средняя по размеру программа становится "огромной".
                                    Цитата andriano @
                                    Фортран не подходит для обработки текста.
                                    Не то чтобы совсем не подходит, но обработка текста на нем имеет свои особенности, делающие этот процесс сильно отличным от обработки текста на C или паскале. Мне лично довелось поработать с несколькими программами, написанными именно на фортране (ничего другого, кроме ассемблера, в распоряжении разработчиков и не было), и занимавшимися исключительно текстовой обработкой, интерпретацией данных и формированием отчетов.

                                    Добавлено
                                    Да, долгое время компиляторы фортрана писались на самом фортране. А это по большей части именно обработка текста
                                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                    0 пользователей:


                                    Рейтинг@Mail.ru
                                    [ Script execution time: 0,0491 ]   [ 16 queries used ]   [ Generated: 23.04.24, 10:01 GMT ]