Read integer statement - fortran90

I am quite new with fortran and have a question. I need to read 2 integers from the following line:
K=234, L=241, I=0
I am not interested in the last value. Just need the integers 234 and 241. I tried it with
read(20,'(3X,I3,3X,I3)')a,b
It compiles, but when I run the program I always get the error message:
At line 27 of file test.f90 (unit = 20, file = 'int_p2.dat')
Fortran runtime error: Bad value during integer read
Don't know what I am doing wrong. Can someone give me some advice?

You have strings in your line, so your READ statement ought to account for it. You should replace it with
READ(20, '(3(a2,i3,2x))') dumChar, k, dumChar, l, dumInt, dumChar
where dumChar is a character of length 2 and dumInt is an integer.

I don't see a problem in your code. (off course, your format is wrong, but should not give runtime error). Also, you are escaping chars (K,L) rather then reading them. compiler should not complain. but 3X will eat up 1 integer for K=234
Program se
Implicit None
integer :: K,L,I,a,b
open(20, file="se.in",status='old')
read(20,'(3X,I3,3X,I3)')a,b
close(20)
write(*,*)a,b
End Program se
$ cat se.in
K=234, L=241, I=0
$gfortran se.f90
$ ./a.out
34 241
If you still getting the problem, and if this are one single line you are trying to read, do
remove any space before K= in the file.
I think this is the error, as the code is reading non-integer.

Related

How does the following quine work?

According to wikipedia :
A quine is a non-empty computer program which takes no input and produces a copy of its own source code as its only output
I saw this piece of perl code and am not able to figure out how it works.
Save the following line in file /tmp/p and run the file as perl /tmp/p:
Illegal division by zero at /tmp/p line 1.
The output of perl /tmp/p is:
Illegal division by zero at /tmp/p line 1.
How is the code working?
First, try to run it with warnings turned on:
$ perl -w p
Unquoted string "at" may clash with future reserved word at p line 1.
Unquoted string "tmp" may clash with future reserved word at p line 1.
Argument "tmp" isn't numeric in division (/) at p line 1.
Argument "at" isn't numeric in division (/) at p line 1.
The first two warnings are from the compile phase.
Let's look at the Deparse output:
$ perl -MO=Deparse p
'division'->Illegal('zero'->by('at' / 'tmp' / 'line'->p(1)));
p syntax OK
In essence, the value of at divided by tmp divided by the return value of another method invocationp is passed as an argument to the method by invoked on the class 'zero'. at and tmp are considered to be strings, and their numeric values are zero. Therefore, at/tmp results in the illegal division by zero error.
You will get the same error if you change the file's contents to
Stackoverflow hacker news one at /tmp/p line 1.
If you are wondering how Illegal division becomes 'division'->Illegal, see indirect object syntax, and avoid using it.
I would prefer to see you concentrating on improving the quality of your Perl code, rather than investigating obscure corners
But the answer is that the line is parsed as
'division'->Illegal('zero'->by('at' / 'tmp' / 'line'->p(1)));
and Perl uses zero for 'at' and 'tmp' because they are not valid numeric strings, so the first action is to evaluate 0 / 0 which throws the error

ValueError when converting to int lines retrieved via getline.linecache

this is my first message here, I hope I will not commit any mistake.
I am writing a python 2.7 script which performs comparisons between lines from a long list of lines provided as an external input file. Some of these lines contain just numbers, and on those I perform simple sums after their retrieval via getline.linecache.
My problem is that after a certain number of lines I am getting the error:
ValueError: invalid literal for int() with base 10
I do understand that somehow this has to do with the fact that there is some problem when I try to convert the lines retrieved to the integer type, but according to what I read each line should be retrieved from a memory database as a string, and indeed if I try to print the type of the values retrieved I get str. I printed the problematic values in order to understand why they failed to be converted to int: at first i included some semantic mistakes (I was taking some wrong lines, which were containing letters, and this of course failed to be converted to int), but still I get the error on merely numerical strings. On all of those numerical strings, I tried len(linecache.getline('input', line_n)) to see if any extra characters were present, but I just found '\n', which does not give any problems when converting from str to int.
My input file is made by a series of lines, some numerical some not; here are few lines:
1
id3021-a
1
129485768
129485769
2
id2034
102
944709842
944709848
For examples, line 4 here can be retrieved, but not converted to int. How could I convert str to int without getting errors?
I found the solution! Adding a '0' to the beginning of the string fixes the problem (I do not know why, the problematic lines were not empty):
int('0' + linecache.getline('input', line_n))
See here: Trouble converting string to int in Django/Python

How to use command line arguments in Fortran?

GCC version 4.6
The Problem: To find a way to feed in parameters to the executable, say a.out, from the command line - more specifically feed in an array of double precision numbers.
Attempt: Using the READ(*,*) command, which is older in the standard:
Program test.f -
PROGRAM MAIN
REAL(8) :: A,B
READ(*,*) A,B
PRINT*, A+B, COMMAND_ARGUMENT_COUNT()
END PROGRAM MAIN
The execution -
$ gfortran test.f
$ ./a.out 3.D0 1.D0
This did not work. On a bit of soul-searching, found that
$./a.out
3.d0,1.d0
4.0000000000000000 0
does work, but the second line is an input prompt, and the objective of getting this done in one-line is not achieved. Also the COMMAND_ARGUMENT_COUNT() shows that the numbers fed into the input prompt don't really count as 'command line arguments', unlike PERL.
If you want to get the arguments fed to your program on the command line, use the (since Fortran 2003) standard intrinsic subroutine GET_COMMAND_ARGUMENT. Something like this might work
PROGRAM MAIN
REAL(8) :: A,B
integer :: num_args, ix
character(len=12), dimension(:), allocatable :: args
num_args = command_argument_count()
allocate(args(num_args)) ! I've omitted checking the return status of the allocation
do ix = 1, num_args
call get_command_argument(ix,args(ix))
! now parse the argument as you wish
end do
PRINT*, A+B, COMMAND_ARGUMENT_COUNT()
END PROGRAM MAIN
Note:
The second argument to the subroutine get_command_argument is a character variable which you'll have to parse to turn into a real (or whatever). Note also that I've allowed only 12 characters in each element of the args array, you may want to fiddle around with that.
As you've already figured out read isn't used for reading command line arguments in Fortran programs.
Since you want to read an array of real numbers, you might be better off using the approach you've already figured out, that is reading them from the terminal after the program has started, it's up to you.
The easiest way is to use a library. There is FLAP or f90getopt available. Both are open source and licensed under free licenses.
The latter is written by Mark Gates and me, just one module and can be learned in minutes but contains all what is needed to parse GNU- and POSIX-like command-line options. The first is more sophisticated and can be used even in closed-source projects. Check them out.
Furthermore libraries at https://fortranwiki.org/fortran/show/Command-line+arguments
What READ (*,*) does is that it reads from the standard input. For example, the characters entered using the keyboard.
As the question shows COMMAND_ARGUMENT_COUNT() can be used to get the number of the command line arguments.
The accepted answer by High Performance Mark show how to retrieve the individual command line arguments separated by blanks as individual character strings using GET_COMMAND_ARGUMENT(). One can also get the whole command line using GET_COMMAND(). One then has to somehow parse that character-based information into the data in your program.
I very simple cases you just need the program requires, for example, two numbers, so you read one number from arg 1 and another form arg 2. That is simple. Or you can read a triplet of numbers from a single argument if they are comma-separated like 1,2,3 using a simple read(arg,*) nums(1:3).
For general complicated command line parsing one uses libraries such as those mentioned in the answer by Hani. You have set them up so that the library knows the expected syntax of the command line arguments and the data it should fill with the values.
There is a middle ground, that is still relatively simple, but one already have multiple arguments, that correspond to Fortran variables in the program, that may or may not be present. In that case one can use the namelist for the syntax and for the parsing.
Here is an example, the man point is the namelist /cmd/ name, point, flag:
implicit none
real :: point(3)
logical :: flag
character(256) :: name
character(1024) :: command_line
call read_command_line
call parse_command_line
print *, point
print *, "'",trim(name),"'"
print *, flag
contains
subroutine read_command_line
integer :: exenamelength
integer :: io, io2
command_line = ""
call get_command(command = command_line,status = io)
if (io==0) then
call get_command_argument(0,length = exenamelength,status = io2)
if (io2==0) then
command_line = "&cmd "//adjustl(trim(command_line(exenamelength+1:)))//" /"
else
command_line = "&cmd "//adjustl(trim(command_line))//" /"
end if
else
write(*,*) io,"Error getting command line."
end if
end subroutine
subroutine parse_command_line
character(256) :: msg
namelist /cmd/ name, point, flag
integer :: io
if (len_trim(command_line)>0) then
msg = ''
read(command_line,nml = cmd,iostat = io,iomsg = msg)
if (io/=0) then
error stop "Error parsing the command line or cmd.conf " // msg
end if
end if
end subroutine
end
Usage in bash:
> ./command flag=T name=\"data.txt\" point=1.0,2.0,3.0
1.00000000 2.00000000 3.00000000
'data.txt'
T
or
> ./command flag=T name='"data.txt"' point=1.0,2.0,3.0
1.00000000 2.00000000 3.00000000
'data.txt'
T
Escaping the quotes for the string is unfortunately necessary, because bash eats the first quotes.

Error message when trying to create a module in fortran 90

I am trying to create a module for a fortran 90 program. The file is called epath.f90. When I try to create the file epath.mod by running an object-only compile on the file by way of the commad f95 -c epath.f90 it gives me the following error message:
epath.f90:1:
MODULE euler-path
1
Error: Unclassifiable statement at (1)
epath.f90:8.3:
END MODULE euler-path
1
Error: Expecting END PROGRAM statement at (1)
Error: Unexpected end of file in 'epath.f90'
The code for epath.f90 is:
MODULE euler-path
INTEGER, PARAMETER :: NSTEPS=10
REAL, PARAMETER :: A=0.0, B=1.0, YSTART=0.0
REAL, DIMENSION(0:NSTEPS) :: x,y
END MODULE euler-path
I took the same steps for another module and it worked fine. Any help is appreciated.
In Fortran, names - module names, variable names, etc - have to start with a letter and contain only letters, digits, or underscores. (Fortran in particular forbids using special characters like operators, eg, -/+/*/(/) in names because it's historically taken a very cavalier approach to the use of spaces, or for that matter explicitly defined variable names, which would make it very difficult to distinguish between a-b as a name and the expression a - b.) See, eg, section 3.2.2 ("Names") of the recent Fortran standard.
So euler_path is ok, euler_path123 is ok, but euler-path isn't.

Printing a number in brainfuck?

I've searched for a while, but i couldn't find anything that could help me.
Let's say the first cell(or value, etc.) equals 165. How do i print "165"?
My idea was to cut the number into seperate pieces: 1,6 and 5. It would than be no problem to print them.
Note: I don't just want to print "165". I want to print the value the first cell has. No matter if it's 165, 255, 0, 1 or anything else.
use a famous modulo procedure ( http://esolangs.org/wiki/brainfuck_algorithms will help you)
>+++++++++++[-<+++++++++++++++>] # initialize 165 at first cell
>++++++++++<<[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]>>[-]>>>++++++++++<[->-[>+>>]>[+[-
<+>]>+>>]<<<<<]>[-]>>[>++++++[-<++++++++>]<.<<+>+>[-]]<[<[->-<]++++++[->++++++++
<]>.[-]]<<++++++[-<++++++++>]<.[-]<<[-<+>]
I have created a simple language that compiles to brainfuck which can be found here: http://code.google.com/p/brainfuck-compiler. There is a compiler for the language implemented in java.
I use the following function in that language to output a number. Maybe you can analyze the generated code and see if anything can be of use to you from it. One word of warning though, it does generate a bit of redundant copying around of cells (never got around to optimizing this). Anyway here's an example program and the BF code it generates. (note that indentations MUST be tabs in my language)
declare n, 165
declare digits
while n
push n % 10
digits = digits + 1
n = n / 10
if digits
while digits
out pop + 48
digits = digits - 1
else
outs "0"
And here is the generated code for that:
>>>>>>>>>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++[<+>-]<[>>+>+<<<-]>>>[<<<+>>>-]<[[-]<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-
]++++++++++<[>>+>+<<<-]>>>[<<<+>>>-]<[>+<-]>[<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[>+
<<-[>>[-]>+<<<-]>>>[<<<+>>>-]<[<-[<<->>[-]]+>-]<-]<<+>]<[>>+<<-]>>[<<<[>+>+<<-]>
>[<<+>>-]>-]<<[<<->>-]<[-]<[>>>>>>>>+<<<<<<<<-]>>>>>>>>>[>>]+[<<]>[>[>>]<+<[<<]>
-]<<<<<<<<<<[>>+>+<<<-]>>>[<<<+>>>-]+[<+>-]<<<[-]>>[<<+>>-]<<<[>>>+>+<<<<-]>>>>[
<<<<+>>>>-]++++++++++<[>>+<<-]>>[<[>>+>+<<<-]>>>[<<<+>>>-]<[>+<<-[>>[-]>+<<<-]>>
>[<<<+>>>-]<[<-[<<<->>>[-]]+>-]<-]<<<+>>]<[-]<<<<[-]>>>[<<<+>>>-]<<<[>>>+>+<<<<-
]>>>>[<<<<+>>>>-]<[<+>-]<]<[>+>+<<-]>>[<<+>>-]<[>+<[-]]+>[<[-]<[>>>+>+<<<<-]>>>>
[<<<<+>>>>-]<[[-]>>>>>>>>[>>]<[<[<<]<<<<<+>>>>>>>[>>]<-]<-<<[<<]<<<<<>++++++++++
++++++++++++++++++++++++++++++++++++++[<+>-]<.[-]<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+
>>>>>-]+[<->-]<<<<<[-]>>>>[<<<<+>>>>-]<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-]<[<+
>-]<]<[-]]<[>>++++++[<++++++++>-]<.[-]<[-]]<[-]<[-]>>>>>>>>>>>>[>[-]>]<<[-<<]<<<
<<<<<<<<<<<<<<[-]<[-]