Related
I'm learning how to programming with fortran90 and i need receive data from a txt file by the command prompt (something like that:
program.exe"<"data.txt).
at the Input txt file I'll always have a single line with at least 6 numbers till infinity.
if the data was wrote line by line it runs fine but as single line I'm receiving the error: "traceback:not available,compile with - ftrace=frame or - ftrace=full fortran runtime error:end file"
*note: i'm using Force fortran 2.0
here is example of data:
0 1 0.001 5 3 1 0 -9 3
edit: just clarifying: the code is working fine itself except for the read statement, which is a simple "read*,". I want know how To read a entire line from a txt once the entrance will be made by the promt command with stream direction.
( you can see more about that here: https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr=true).
there is no need to read the code, i've posted it just for knowledge.
I'm sorry about the whole inconvenience.
here is the code so far:
program bissecao
implicit none
integer::cont,int,e,k,intc,t1,t2,t3
doubleprecision::ii,is,pre,prec,erro,somaa,somab,xn
doubleprecision,dimension(:),allocatable::co
t1=0
t2=0
t3=0
! print*,"insira um limite inf da funcao"
read*,ii
!print*,"insira o limite superior da func"
read*,is
! print*,"insira a precisÆo admissivel"
read*,pre
if (erro<=0) then !elimina criterio de parada negativo ou zero
Print*,"erro"
go to 100
end if
!print*,"insira a qtd iteracoes admissiveis"
read*,int
!print*,"insira o grau da f(x)"
read*,e
if (e<=0) then ! elimina expoente negativo
e=(e**2)**(0.5)
end if
allocate(co(e+1))
!print*, "insira os coeficientes na ordem:&
! &c1x^n+...+(cn-1)x^1+cnx^0"
read(*,*)(co(k),k=e+1,1,-1)
somab=2*pre
intc=0
do while (intc<int.and.(somab**2)**0.5>pre.and.((is-ii)**2)**0.5>pre)
somab=0
somaa=0
xn =(ii+is)/2
do k=1,e+1,1
if (ii /=0) then
somaa=ii**(k-1)*co(k)+somaa
else
somaa=co(1)
end if
! print*,"somaa",k,"=",somaa
end do
do k=1,(e+1),1
if (xn/=0) then
somab=xn**(k-1)*co(k)+somab
else
somab=co(1)
end if
!print*,"somab",k,"=",somab
end do
if ((somaa*somab)<0) then
is=xn
else if((somaa*somab)>0)then
ii=xn
else if ((somaa*somab)==0) then
xn=(ii+is)/2
go to 100
end if
intc =intc+1
prec=is-ii
if ((((is-ii)**2)**.5)< pre) then
t3=1
end if
if (((somab**2)**.5)< pre) then
t2=1.
end if
if (intc>=int) then
t1=1
end if
end do
somab=0
xn=(ii+is)/2
do k=1,(e+1),1
if (xn/=0) then
somab=xn**(k-1)*co(k)+somab
else
somab=co(1)
end if
end do
100 write(*,'(A,F20.15,A,F20.15,A,A,F20.15,A,F20.15,A,I2)'),"I:[",ii,",",is,"]","raiz:",xn,"Fraiz:",somab,"Iteracoes:",intc
end program !----------------------------------------------------------------------------
In your program, you are using the "list-directed input" (i.e., read *, or read(*,*))
read *, ii
read *, is
read *, pre
read *, int
read *, e
read *, ( co( k ), k = e+1, 1, -1 )
which means that the program goes to the next line of the data file after each read statement (by neglecting any remaining data in the same line). So, the program works if the data file (say "multi.dat") consists of separate lines (as suggested by OP):
0
1
0.001
5
3
1 0 -9 3
But now you are trying to read an input file containing only a single line (say "single.dat")
0 1 0.001 5 3 1 0 -9 3
In this case, we need to read all the values with a single read statement (if list-directed input is to be used).
A subtle point here is that the range of array co depends on e, which also needs to be read by the same read statement. A workaround might be to just pre-allocate co with a sufficiently large number of elements (say 100) and read the data in a single line, e.g.,
integer :: k
allocate( co( 100 ) )
read *, ii, is, pre, int, e, ( co( k ), k = e+1, 1, -1 )
For completeness, here is a test program where you can choose method = 1 or 2 to read "multi.dat" or "single.dat".
program main
implicit none
integer :: int, e, k, method
double precision :: ii, is, pre
double precision, allocatable :: co(:)
allocate( co( 1000 ) )
method = 1 !! 1:multi-line-data, 2:single-line-data
if ( method == 1 ) then
call system( "cat multi.dat" )
read*, ii
read*, is
read*, pre
read*, int
read*, e
read*, ( co( k ), k = e+1, 1, -1 )
else
call system( "cat single.dat" )
read*, ii, is, pre, int, e, ( co( k ), k = e+1, 1, -1 )
endif
print *, "Input data obtained:"
print *, "ii = ", ii
print *, "is = ", is
print *, "pre = ", pre
print *, "int = ", int
print *, "e = ", e
do k = 1, e+1
print *, "co(", k, ") = ", co( k )
enddo
end program
You can pass the input file from standard input as
./a.out < multi.dat (for method=1)
./a.out < single.dat (for method=2)
Please note that "multi.dat" can also be read directly by using "<".
I have to compute few complex integrals and for this purpose I got from my supervisor old program written in Fortran 77. However I have few problems with it. Mostly associated with syntax errors of DATA Statement. This is a part of code with a function calculating real integrals:
FUNCTION CAUSSA(F,A,B,EPS)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
external f
REAL :: W(12),X(12)
DATA CONST /1.0D-12/
DATA W &
1 /0.10122 85362 9037 , 0.22238 10344 5337 , 0.31370 66458 7788 ,&
2 0.36268 37833 7836 , 0.02715 24594 1175 , 0.06225 35239 3864 ,&
3 0.09515 85116 8249 , 0.12462 89712 5553 , 0.14959 59888 1657 ,&
4 0.16915 65193 9500 , 0.18260 34150 4492 , 0.18945 06104 5506 /
DATA X &
1 /0.96028 98564 9753 , 0.79666 64774 1362 , 0.52553 24099 1632 ,&
2 0.18343 46424 9565 , 0.98940 09349 9165 , 0.94457 50230 7323 ,&
3 0.86563 12023 8783 , 0.75540 44083 5500 , 0.61787 62444 0264 ,&
4 0.45801 67776 5722 , 0.28160 35507 7925 , 0.09501 25098 3763 /
DELTA=CONST*DABS(A-B)
CAUSSA=0.d0
AA=A
5 Y=B-AA
IF(DABS(Y) .LE. DELTA) RETURN
2 BB=AA+Y
C1=0.5*(AA+BB)
C2=C1-AA
S8=0.d0
S16=0.d0
DO 1 I=1,4
U=X(I)*C2
1 S8=S8+W(I)*(F(C1+U)+F(C1-U))
DO 3 I = 5,12
U=X(I)*C2
3 S16=S16+W(I)*(F(C1+U)+F(C1-U))
S8=S8*C2
S16=S16*C2
IF(DABS(S16-S8).GT.EPS*DABS(S16)) GO TO 4
CAUSSA= CAUSSA+S16
A=BB
GO TO 5
4 Y=0.5*Y
IF(DABS(Y) .GT. DELTA) GO TO 2
write(2,7)
write(5,7)
7 FORMAT(1X,35HCAUSSA...TOO HIGH ACCURACY REQUIRED)
CAUSSA=0.d0
RETURN
END
The result of compilation is following:
sample.f90:11:
1 /0.10122 85362 9037 , 0.22238 10344 5337 , 0.31370 66458 7788 ,&
1
Error: Syntax error in DATA statement at (1)
sample.f90:17:
1 /0.96028 98564 9753 , 0.79666 64774 1362 , 0.52553 24099 1632 ,&
1
Error: Syntax error in DATA statement at (1)
I use gfortran version 4.4.7. I tried to rewrite those arrays but the result is always the same. Although this function is not the best for integrating, I still need it. Without it, that old program is collapsing.
I would appreciate any advice.
If you want to compile this as free form source, there are two things you will probably need to change
I am pretty sure that labels are illegal in continuation lines, so they should be removed
gfortran will misinterpreted the spaces between sections of the floating point numbers, so those also should be removed.
Something like this:
DATA W &
/0.10122853629037 , 0.22238103445337 , 0.31370664587788 ,&
0.36268378337836 , 0.02715245941175 , 0.06225352393864 ,&
0.09515851168249 , 0.12462897125553 , 0.14959598881657 ,&
0.16915651939500 , 0.18260341504492 , 0.18945061045506 /
should probably compile correctly [note written in browser and not tested].
Your original code was erroneously mixing both free-form and fixed-source format. Line continuations in free-form are performed by using a trailing ampersand character, &, rather than entering a character in column 6 of the following line. In fixed-source form, the first six columns are reserved for statement labels, with column 1 also used to indicate comment lines. In modern code, using structured control statements (such as select case or if-then-else) statement labels are uncommon. The first five columns are therefore wasted because they are rarely used.
Here is the same code in free-form and fixed-source format:
program main
use ISO_Fortran_env, only: &
compiler_version, &
compiler_options
! Explicit typing only
implicit none
! Variable declarations
double precision :: a, b, eps, x
a = 1.0d0
b = 2.0d0
eps = epsilon(a)
x = caussa(my_func, a, b, eps)
print '(/4a/)', &
' This file was compiled using ', compiler_version(), &
' using the options ', compiler_options()
contains
function my_func(arg) result (return_value)
! Dummy arguments
double precision, intent (in) :: arg
double precision :: return_value
return_value = arg * 42.0d0
end function my_func
function caussa(f,a,b,eps)
use ISO_Fortran_env, only: &
stderr => ERROR_UNIT
implicit double precision (a-h,o-z)
external f
integer :: i
real :: w(12),x(12)
data const /1.0d-12/
data w &
/0.10122853629037, 0.22238103445337, 0.31370664587788 ,&
0.36268378337836, 0.02715245941175, 0.06225352393864 , &
0.09515851168249, 0.12462897125553, 0.14959598881657 , &
0.16915651939500, 0.18260341504492, 0.18945061045506 /
data x &
/0.96028985649753, 0.79666647741362, 0.52553240991632, &
0.18343464249565, 0.98940093499165, 0.94457502307323, &
0.86563120238783, 0.75540440835500, 0.61787624440264, &
0.45801677765722, 0.28160355077925, 0.09501250983763 /
delta=const*dabs(a-b)
caussa=0.d0
aa=a
5 y=b-aa
if (dabs(y) <= delta) return
2 bb=aa+y
c1=0.5*(aa+bb)
c2=c1-aa
s8=0.d0
s16=0.d0
do 1 i=1,4
u=x(i)*c2
1 s8=s8+w(i)*(f(c1+u)+f(c1-u))
do 3 i = 5,12
u=x(i)*c2
3 s16=s16+w(i)*(f(c1+u)+f(c1-u))
s8=s8*c2
s16=s16*c2
if (dabs(s16-s8)>eps*dabs(s16)) go to 4
caussa = caussa+s16
a = bb
go to 5
4 y = 0.5*y
if (dabs(y) > delta) go to 2
write(2,7)
write(stderr,7)
!
! 7 format(1x,35hcaussa...too high accuracy required)
! Hollerith format specifier is a Fortran 95 deleted feature
!
7 format(1x, 'caussa...too high accuracy required')
caussa=0.d0
end function caussa
end program main
Here's the fixed-form version
PROGRAM MAIN
USE ISO_FORTRAN_ENV, ONLY:
1 COMPILER_VERSION,
2 COMPILER_OPTIONS
C EXPLICIT TYPING ONLY
IMPLICIT NONE
C VARIABLE DECLARATIONS
DOUBLE PRECISION :: A, B, EPS, X
A = 1.0D0
B = 2.0D0
EPS = EPSILON(A)
X = CAUSSA(MY_FUNC, A, B, EPS)
PRINT '(/4A/)',
1 ' THIS FILE WAS COMPILED USING ', COMPILER_VERSION(),
2 ' USING THE OPTIONS ', COMPILER_OPTIONS()
CONTAINS
FUNCTION MY_FUNC(ARG) RESULT (RETURN_VALUE)
C DUMMY ARGUMENTS
DOUBLE PRECISION, INTENT (IN) :: ARG
DOUBLE PRECISION :: RETURN_VALUE
RETURN_VALUE = ARG * 42.0D0
END FUNCTION MY_FUNC
FUNCTION CAUSSA(F,A,B,EPS)
USE ISO_FORTRAN_ENV, ONLY:
1 STDERR => ERROR_UNIT
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
EXTERNAL F
INTEGER I
REAL :: W(12), X(12)
DATA CONST /1.0D-12/
DATA W
1 /0.10122 85362 9037, 0.22238 10344 5337, 0.31370 66458 7788,
2 0.36268 37833 7836, 0.02715 24594 1175, 0.06225 35239 3864,
3 0.09515 85116 8249, 0.12462 89712 5553, 0.14959 59888 1657,
4 0.16915 65193 9500, 0.18260 34150 4492, 0.18945 06104 5506 /
DATA X
1 /0.96028 98564 9753, 0.79666 64774 1362, 0.52553 24099 1632,
2 0.18343 46424 9565, 0.98940 09349 9165, 0.94457 50230 7323,
3 0.86563 12023 8783, 0.75540 44083 5500, 0.61787 62444 0264,
4 0.45801 67776 5722, 0.28160 35507 7925, 0.09501 25098 3763 /
DELTA=CONST*DABS(A-B)
CAUSSA=0.D0
AA=A
5 Y=B-AA
IF(DABS(Y) .LE. DELTA) RETURN
2 BB=AA+Y
C1=0.5*(AA+BB)
C2=C1-AA
S8=0.D0
S16=0.D0
DO 1 I=1,4
U=X(I)*C2
1 S8=S8+W(I)*(F(C1+U)+F(C1-U))
DO 3 I = 5,12
U=X(I)*C2
3 S16=S16+W(I)*(F(C1+U)+F(C1-U))
S8=S8*C2
S16=S16*C2
IF(DABS(S16-S8).GT.EPS*DABS(S16)) GO TO 4
CAUSSA= CAUSSA+S16
A=BB
GO TO 5
4 Y=0.5*Y
IF(DABS(Y) .GT. DELTA) GO TO 2
WRITE(2,7)
WRITE(STDERR,7)
C
C 7 FORMAT(1X,35HCAUSSA...TOO HIGH ACCURACY REQUIRED)
C HOLLERITH FORMAT SPECIFIER IS A FORTRAN 95 DELETED FEATURE
C
7 FORMAT(1X, 'CAUSSA...TOO HIGH ACCURACY REQUIRED')
CAUSSA=0.D0
RETURN
END FUNCTION CAUSSA
END PROGRAM MAIN
With free-form, the concept of “significant blanks” was introduced.
In fixed-source, blanks were insignificant in most contexts. Here is a sample of a fixed-source statement showing what are now considered significant blanks followed by an equivalent statement without the blanks:
DO N = 1, MAX ITER S
DO N = 1, MAXITERS
Notice how we rewrote
DATA W
1 /0.10122 85362 9037, blah blah
as
data w &
/0.10122853629037, blah blah
I have put a check in error made in the input as:
integer :: lsp
chksp:do
write(*,*) "#Enter Number"
read(*,*,iostat=istat)lsp
if (istat==0) then
exit chksp
else
write(*,*)"Number can only be integer. Re-enter!"
end if
end do chksp
The problem is, it can detect error if a character value in enteres, instead of a numeric value; but it cannot detect error, if a real value is entered, instead of a integer.
Any way to force it detect integer only?
NB: May be problem with ifort; gfortran is happy with the code.
You can specify the format to request an integer:
program enter_int
implicit none
integer :: ierror, intVal
do
write(*,*) "Enter an integer number"
read(*,'(i10)',iostat=ierror) intval
if ( ierror == 0 ) then
exit
endif
write(*,*) 'An error occured - please try again'
enddo
write(*,*) 'I got: ', intVal
end program
Then, providing a float fails.
Something like the following?
ian#ian-pc:~/test/stackoverflow$ cat read.f90
Program readit
Integer :: val
Integer :: iostat
val = -9999
Do
Read( *, '( i20 )', iostat = iostat ) val
If( iostat == 0 ) Then
Write( *, * ) 'val = ', val
Else
Write( *, * ) 'oh dear!!'
End If
End Do
End Program readit
ian#ian-pc:~/test/stackoverflow$ nagfor -o read read.f90
NAG Fortran Compiler Release 5.3.1(907)
[NAG Fortran Compiler normal termination]
ian#ian-pc:~/test/stackoverflow$ ./read
10
val = 10
10.0
oh dear!!
safs
oh dear!!
123dfs23
oh dear!!
^C
ian#ian-pc:~/test/stackoverflow$ gfortran -o read read.f90
ian#ian-pc:~/test/stackoverflow$ ./read
10
val = 10
10.0
oh dear!!
dsfs
oh dear!!
^C
ian#ian-pc:~/test/stackoverflow$
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
Recently, I started to lean fortran programming. I have seen the following code at youtube without any error it is compiled. But I have got some errors.
I appreciate any help
program
implicit none
real, parameter :: pi=4*atan(1.0)
integer, parameter :: n = 100
real :: dimension(1:n) :: x, y
real :: a=0.0, b = 2*pi
real :: increment
integer :: i
increment = (b-a)/(real(n)-1)
x(1)=0.0
do i =2,n
x(i) = x(i-1) + increment
end do
y = sin(x)
print *, x(1:5)
print *, y(1:5)
end program
real :: dimension(1:n) :: x, y is a syntax error. Replace the first :: with a comma. You may need to give a name on the program statement.
You also have mixed-mode arithmetic in line
increment = (b-a)/(real(n)-1)
It will probably compile, and it may not even affect the program, but you should never, never have mixed-mode arithmetic in any programming language as it can cause strange, hard to find bugs.
It should look like this:
increment = (b-a)/(real(n)-1.0)
Here are the results of a working example which addresses the concerns of #High Performance Mark.
host system = (redacted)
compiler version = GCC version 5.1.0
compiler options = -fPIC -mmacosx-version-min=10.9.4 -mtune=core2 -Og -Wall -Wextra -Wconversion -Wpedantic -fmax-errors=5
execution command = ./a.out
Compare mesh points
1.57017982 1.57080817 1.57143652
1.57016802 1.57079625 1.57142460
Compare function values at these mesh points
1622.04211 -84420.7344 -1562.01758
1591.57471 13245402.0 -1591.65527
There is a bad programming practice in the demo you found: moving through the mesh by adding steps (+ increment) instead of counting them (k * increment). The problem is widespread and appears with severe consequences (https://www.ima.umn.edu/~arnold/disasters/patriot.html).
For demonstration on your code, the size of the mesh was boosted to 10K points. Also the sample function changed from cos x to tan x and we examine points near the singularity at pi/2 = 1.57079633. While the novitiate may find the discrepancies in mesh values trivial, the difference in function values is significant.
(Mesh errors can be reduced by using increments which have exact binary representation like 2^(-13) = 1 / 8192.)
The code is shown here. The compilation command is gfortran -Wall -Wextra -Wconversion -Og -pedantic -fmax-errors=5 demo.f95. The run command is ./a.out.
program demo
use iso_fortran_env
implicit none
real, parameter :: pi = acos ( -1.0 )
integer, parameter :: n = 10001
real, dimension ( 1 : n ) :: x, y, z
real :: a = 0.0, b = 2 * pi
real :: increment
integer :: k, quarter, status
character ( len = * ), parameter :: c_options = compiler_options( )
character ( len = * ), parameter :: c_version = compiler_version( )
character ( len = 255 ) :: host = " ", cmd = " "
! queries
call hostnm ( host, status )
call get_command ( cmd )
! write identifiers
write ( *, '( /, "host system = ", g0 )' ) trim ( host )
write ( *, '( "compiler version = ", g0 )' ) c_version
write ( *, '( "compiler options = ", g0 )' ) trim ( c_options )
write ( *, '( "execution command = ", g0, / )' ) trim ( cmd )
increment = ( b - a ) / ( n - 1 )
quarter = n / 4
! mesh accumulates errors
x ( 1 ) = 0.0
do k = 2, n
x ( k ) = x ( k - 1 ) + increment
end do
y = tan ( x )
print *, 'Compare mesh points'
print *, x ( quarter : quarter + 2 )
! better mesh
x ( 1 ) = 0.0
do k = 2, n
x ( k ) = ( k - 1 ) * increment
end do
z = tan ( x )
print *, x ( quarter : quarter + 2 )
print *, 'Compare function values at these mesh points'
print *, y ( quarter : quarter + 2 )
print *, z ( quarter : quarter + 2 )
end program demo
I am attempting read a large data file into Fortran it contains about 40960000 rows, I later convert it to a matrix so it would be 6400 * 6400. When I try my code using a much smaller data set it works fine. However, it tells me that there is a segmentation fault, when I use my larger dataset. I suspect that it is a memory allocation issue. Is there a way to allocate more memory or otherwise correct this problem.
program infectgrid
implicit none
integer :: i, individual, nedge,&
tempinfect_tim_err, dumnum_infalpha0, dumnum_infalpha1, alpha0counter, &
alpha1counter, obsrand, minvalshift
character (LEN = 50) :: parameterfilelabel, parameterfile, networkfilelabel, infectfilenamelabel, networkfile, infectfilename
!allocatable to allow for reading in of individuals and time periods
integer, dimension(:) , allocatable :: xcord, ycord, dummy3, recover_tim1, recover_tim2, &
recover_tim3, recover_tim4, recover_tim5, sampleadjshort, shortsamplecount, &
cov1dum, covlog, covvect1uni
character, dimension (:), allocatable :: rec
integer, dimension (:, :) , allocatable :: link
real, dimension(:) , allocatable :: alphavect
call random_seed
open(12, file = "filenamesinfection.txt", status = "old")
read(12, *) parameterfile, networkfile, infectfilename
close(12)
open(12, file = parameterfile, status = "old")
read(12, *) individualname, alpha0name, alpha1name
read(12, *) individual, alpha0, alpha1
nedge = individual*individual
allocate(rec(1:nedge))
allocate(xcord(1:nedge))
allocate(ycord(1:nedge))
allocate(dummy3(1:nedge))
allocate(sampleadjshort(1:nedge))
allocate(shortsamplecount(1:nedge))
allocate(covlog(1:nedge))
allocate(cov1dum(1:nedge))
allocate(link(1:individual, 1:individual))
link = 0
covlog = 0
print *, individual, alpha0, alpha1
print *, link(individual, individual)
print *, "test"
open(10, file = networkfile, status = "old")
print *, networkfile
print *, "test"
do i = 1, nedge
read ( 10, *) rec(i), xcord(i), ycord(i), dummy3(i), cov1dum(i), sampleadjshort(i), shortsamplecount(i)
if (dummy3(i) == 1) then
link(xcord(i), ycord(i)) = 1
end if
if (xcord(i) == ycord(i)) then
covlog(i) = 1
end if
end do
close(10)
covvect1uni = pack(cov1dum, covlog == 1)
print *, "xcord", xcord(nedge), "ycord", ycord(nedge)
print *, link(individual, individual)
print *, "test"
The file prints out the first and second "test" but does not print out the link statement nor the line starting with "xcord" and soon after gives me a segmentation fault i.e. Segmentation fault nohup ./swnetworkinfectrecoveralpha05covgeo2.out
as to compiler options, I think that I am using most of what is available: ifort -free -O2 -stand f03 -check bounds -traceback -warn all -fstack-protector -assume protect_parens -implicitnone -o swnetworkinfectrecoveralpha05covgeo2.out swnetworkinfectrecoveralpha05covgeo2.f90