1

My problem is that I want to inquire for an unknown filename in Fortran by using the extension of the file.

Example: a folder has a file with an extension "*.cel", the extension is always the same but the filename can be different because is given by the end-users. I want to detect whether any *.cel exists in the folder and get the name of the file.

  • 1
    you need to work with `execute_command_line` see here for example http://stackoverflow.com/q/40117357/1004168 – agentp Mar 23 '17 at 20:49

2 Answers2

2

This kind of file system interaction is a bit hard. You'd think that someone would have created a module for that, but there are precious few, and I haven't come across one that was easy to use.

What most people do is either use a specific call to the system or execute_command_line subroutines to let the shell do the work, see here:

program my_ls

    use iso_fortran_env
    implicit none
    character(len=*), parameter :: ls_file = '/tmp/my_ls.tmp'
    integer :: u, ios
    character(len=30) :: filename

    call execute_command_line('ls -1 > '//ls_file, wait=.TRUE., exitstat=ios)
    if (ios /= 0) stop "Unable to get listing"

    open(newunit=u, file=ls_file, iostat=ios, status="old", action="read")
    if ( ios /= 0 ) stop "Error opening listing file "

    do
        read(u, *, iostat=ios) filename
        if (is_iostat_end(ios)) exit
        if (ios /= 0) STOP "Unexpected error while reading listing file"
        if (index(filename, ".cel") > 0) then
            print*, filename
        end if
    end do

    close(u)

    call execute_command_line('rm '//ls_file, wait=.FALSE.)

end program my_ls

But what would be easier is to give the filenames as a command line argument when starting the program:

program my_ls2

    use iso_fortran_env
    implicit none

    integer :: num_files, i
    character(len=64), allocatable :: filenames(:)

    num_files = command_argument_count()
    allocate(filenames(num_files))
    do i = 1, num_files
        call get_command_argument(i, filenames(i))
    end do

    write(*, '(A)') filenames

end program my_ls2

Calling this program with

$ my_ls2 *.cel

will give you every file you want.

chw21
  • 7,970
  • 1
  • 16
  • 31
  • Just a note: In the first example, it would probably be safer, simpler, and faster, to let the `ls` command do the checking for the `.cel` extension: `'ls -1 *.cel > ' // ls_file`, but I wanted to leave the `index` call in to show an example for how to look for filename parts. – chw21 Mar 24 '17 at 01:04
  • Just wanted to point out you are assuming the poster is always in a Unix like environment via the use of ls, or at least an environment where ls lists files – Ian Bush Mar 24 '17 at 07:40
  • You are of course right. However, if I were using another operating system, I would probably use the corresponding commands. So this should give even windows users a pointer to how this can be done – chw21 Mar 25 '17 at 09:58
1

Simple answer: I'm afraid you can't do that in standard Fortran. You're going to have to look at your compiler documentation to find if it supports an extension through which you can implement what you require.

Ian Bush
  • 6,996
  • 1
  • 21
  • 27