whatsherface
whatsherface

Reputation: 413

Invalid chacter in name fortran 90

This is probably something really simple but I'm getting the error when compiling my little Fortran program. (The file is .f90) Is this something to do with fixed versus free line length? That seems to be all I could glean from a google search.

Here's the program:

program array
    integer :: k, n, i, j, h, f, AllocateStatus
    real*8, dimension(:, :, :), allocatable :: a
    character, parameter :: "fname"

k = 5
n = 5
h = 1
    allocate(a(n,k,h), stat = AllocateStatus)
    if (AllocateStatus /= 0) stop "*** Not enough memory ***"

    a(1,:,:) = 5
a(2,:,:) = 6

call writeArray(7,a,"testOutput")

deallocate(a)

end program array

subroutine writeArray(f,array,fname)
implicit none
integer :: f, i, j, k, n
character, parameter :: "fname"
real*8, dimension(:, :, :), allocatable :: array
        open(unit = f, file="fname")
    do, i=1,n
        do, j=1,k
                write(7,"(F5.2)") array(i,j,:)  
        if (j==k) write(7,"(A1)") "X"
        enddo
    enddo
    !write(7,"(I5)") size(a)

    close(f)
end subroutine writeArray

And the errors:

test.f90:4.29:

character, parameter :: "fname"
                         1
Error: Invalid character in name at (1)
test.f90:24.26:

character, parameter :: "fname"
                      1
Error: Invalid character in name at (1)
test.f90:21.35:

subroutine writeArray(f,array,fname)
                               1
Error: Symbol 'fname' at (1) has no IMPLICIT type

Upvotes: 1

Views: 4460

Answers (3)

Timothy Brown
Timothy Brown

Reputation: 2280

I totally agree with @kyle. So in heeding those suggestions I would also declare the intent of the variables to the subroutine writeArray. Thus the program would be along the lines of:

program array
    integer :: k, n, h, AllocateStatus
    double precision, dimension(:, :, :), allocatable :: a
    character(len=1024) :: fname

    fname = "testOutput"
    k = 5
    n = 5
    h = 1
    allocate(a(n,k,h), stat = AllocateStatus)
    if (AllocateStatus /= 0) stop "*** Not enough memory ***"

    a(1,:,:) = 5
    a(2,:,:) = 6

    call writeArray(7,a,fname)

    deallocate(a)

contains

subroutine writeArray(f,array,fname)
    implicit none
    integer,                    intent(in) :: f
    integer                                :: i, j, k
    character(len=*),           intent(in) :: fname
    double precision, dimension(:, :, :), intent(in) :: array

    open(unit = f, file=fname)
    i = size(array, 1)
    k = size(array, 2)
    do, i=1,n
        do, j=1,k
                write(7,"(F5.2)") array(i,j,:)..
        if (j==k) write(7,"(A1)") "X"
        enddo
    enddo
    !write(7,"(I5)") size(a)

    close(f)
end subroutine writeArray

end program array 

Also I don't like using real*8, I tend to either declare it as either real(kind=8) or double precision.

Lastly, depending on the compiler you use (and hence it's flags), Try to always be as pedantic and chatty as possible. For gfortran I typically use the options -Wall -pedantic when compiling.

Upvotes: 2

M. S. B.
M. S. B.

Reputation: 29391

Additional comments:

You definitely don't want parameter in the declaration of fname -- that designates that the "variable" is constant, which is inconsistent with a dummy argument.

You could declare the arguments as:

integer, intent (in) :: f
character (len=*), intent (in) :: fname
real*8, dimension(:, :, :), intent (in) :: array

The reason that you don't need to declare array as allocatable in the subroutine is that you don't change its allocation in the subroutine. You can obtain the values of n and k with the size intrinsic and so don't need to pass them as arguments.

Upvotes: 2

Kyle Kanos
Kyle Kanos

Reputation: 3264

You cannot use quotation marks to denote an initialization. In your subroutine, you should have

CHARACTER(LEN=*) :: fname

in place of what you have there. You probably do not need the PARAMETER statement with the character declaration. The initialization of fname does not appear to be needed in the main program.

Another pair of things I noted in your code: (1) you don't need to declare array and ALLOCATABLE and (2) you ought to start file UNITs at values >= 10 because the single-digit numbers are occasionally associated with (reserved for?) standard out.


Another suggestion is that you should either put your writeArray subroutine in its own MODULE and USE it, or write the program as

PROGRAM Main
...
CONTAINS
  SUBROUTINE writeArray
  ...
  END SUBROUTINE
END PROGRAM

With either method, you will catch inconsistencies in the arguments. Not only that, you will also be able to use the variables n and k without issue.

Upvotes: 3

Related Questions