I'm trying to write data to binary file from ionosphere model without any special symbols, but now i get 2C000000 (6.165713e-44) - value, that spoil my research. I'm try to fix that, by changing of open command, i'm try add fileopt parameter, but get error.
I'm compile this by gfortran
open(unit = 7,file="iri2016.bin",fileopt = 'NOPAD',
& form = "unformatted",recl = 44)
The fileopt= specifier is not standard Fortran. It is also not needed, do not use it.
Use either the direct unformatted or stream unformatted access.
Related
What's the best way to check whether a given netCDF file exists in Fortran90? I have a Fortran program which simulates several systems and stores the data in a NETCDF file, and I'd like to be able to set it up so that I can run the code with already-existing netCDF files and just append the extra data.
It seems to work with the following:
status = nf90_open(filePath, NF90_WRITE, netcdfID)
if (status /= nf90_noerr) then
new_status = nf90_create(filePath, NF90_NETCDF4, netcdfID)
! setup
else
! check file has correct dimensions etc
end if
But I'd like to be able to be specific about the error, but the documentation isn't very specific about what the error code is when the file already exists.
I've also considered checking the status of the nf90_create(...) call, but I don't know how to specify cmode=NF90_NETCDF4 and cmode=NF90_NOCLOBBER at the same time.
To be honest, when I use NetCDF with Fortran and need to look at the documentation, I look at the C-documentation at https://www.unidata.ucar.edu/software/netcdf/docs/modules.html and 'translate' it to the Fortran API (for example replacing the nc_ with nf90_) because the C documentation is far more current than the Fortran one.
There seem to be these possible status results:
NF90_NOERR No error.
NF90_EPERM Attempting to create a netCDF file in a directory where you do not have permission to open files.
NF90_ENFILE Too many files open
NF90_ENOMEM Out of memory.
NF90_EHDFERR HDF5 error. (NetCDF-4 files only.)
NF90_EDIMMETA Error in netCDF-4 dimension metadata. (NetCDF-4 files only.)
None of these suggest that you were opening a file that doesn't exist. Maybe try it out?
But if you only want to know whether the file already exists, why not use Fortran's INQUIRE statement?
logical :: fileExists
...
inquire(file=filePath, exist=fileExists)
if (fileExists) then
call nf90_open(
else
call nf90_create(
end if
I need to create a file in fortran and then read the data in the file.
call execute_command_line('pwd > workdir.dat')
open(unit=10, file='workdir.dat', status='replace', IOSTAT=open_stat)
if (open_stat /= 0) stop "Reading workdir.dat file Error"
read(10,"(A)") workdir
close(10)
However, workdir.dat is empty when I try to open it, giving me serious open error. It seems that the system only flush the content of workdir.dat to the file at the end of the program. How do I make sure workdir.dat is ready to use before open ?
The open statement includes the clause status=replace which, in effect, tells the run time system that to discard the file's contents and write them anew. To be precise, the language standard states wrt to the status specifier on an open statement:
If REPLACE is specified and the file does exist, the file is deleted,
a new file is created with the same name, and the status is changed to
OLD.
Change the clause to status=old which is the correct specification for this case.
While compiling an OCaml application I get the following error:
File "/tmp/ocamlpp466ee0", line 308, characters 34-233:
Error: Signature mismatch:
...
The field `unlock' is required but not provided
The field `lock' is required but not provided
Command exited with code 2.
My guess is that the error is releated with the OCaml library Datalog (I've installed the version 0.3 from here) because the line 308 in the file is /tmp/ocamlpp466ee0 the first one in the following code
module Logic = Datalog.Logic.Make(struct
type t = atom
let equal = eq_atom
let hash = hash_atom
let to_string a = Utils.sprintf "%a" pp_atom a
let of_string s = atom_of_json (Json.from_string s)
end)
I would really appreciate if someone could help me to know what I am doing wrong.
Moreover, I would like to undestand why the file /tmp/ocamlpp466ee0 is generated each time I execute 'make'? I tried to understand by reading the Makefile but I did not succeed.
I think that something have changed in Datalog library and in some version > 0.3 functor Datalog.Logic.Make requires module argument with values lock and unlock declared. So, it's version problem.
About temporary file. As you can see, its name consists of ocaml literal, pp which means preprocessor and some number. Preprocessors in OCaml usually work this way: they read input source file and write output source files. That's why some temporary files are created.
I would like to know if in Fortran it is possible to use just a single command (with options/specifiers) to do the following:
open a file if it exists and append some data
(this can be done with: open(unit=40,file='data.data',Access = 'append',Status='old') but if the file does not exist a runtime error is issued)
create the file if it does not exist and write some data.
I am currently using inquire to check whether the file exist or not but then I still have to use the open statement to append or write data.
As far as I am aware of, the only safe solution is to do the way you're already doing it, using different open statements for the different cases:
program proba
implicit none
logical :: exist
inquire(file="test.txt", exist=exist)
if (exist) then
open(12, file="test.txt", status="old", position="append", action="write")
else
open(12, file="test.txt", status="new", action="write")
end if
write(12, *) "SOME TEXT"
close(12)
end program proba
You may be interested in my Fortran interface library to libc file system calls (modFileSys), which could at least spare you the logical variable and the inquire statement by querying the file status directly:
if (file_exists("test.txt")) then
...
else
...
end if
but of course you can program a similar function easily yourself, and especially it won't save you from the two open statements...
open(61,file='data.txt',action='write',position='append')
write(61,*) 'hey'
close(61)
This will append to an existing file, otherwise create and write. Adding status='unknown' would be equivalent.
if you replace the status from 'old' to 'unknown' then you will not get the run time error if the file exists or now.
Thanks
In open statement add the attribute access as follows;
Open(unit=031,file='filename.dat',form='formatted',status='unknown',access='append')
The above statement will open the file without destroying old data and write command will append the new lines in the file.
The simplest solution for fortran 90.
I am trying to compile someone else's FORTRAN code using gfortran 4.4.6. The original coder used something like Compaq FORTRAN.
The code in question is supposed to read a filename like 'foo.txt' and create a new file called 'foo_c.txt':
file_label_end = SCAN(filename, '.') - 1
WRITE (output_filename,5) filename
5 FORMAT (A<file_label_end>, '_c.txt' )
gfortran complains about the opening angle bracket of the character specifier. That is, rather than "A3" he has "A<(a variable with value 3)>". I cannot find any information about interpolating format widths from variables... Is this possible? If not, what's the best way to fix this?
Update:
This seems to be working (compiling):
file_label_end = SCAN(par_filename, '.', .TRUE. ) + 1
output_filename = par_filename(1:file_label_end) // '_c.par'
but I later have a similar case:
12 FORMAT (<n-1>F10.5)
...
READ(1,12) (cat_parm (blk,j), j = 1,n-1)
which I attempted to fix by creating a format string:
write(fmt12,'(I0,A4)') n-1, 'F10.5'
!12 FORMAT (fmt12)
12 FORMAT (fmt=fmt12)
But the "t" in "fmt" gets flagged with an error about "Nonnegative width required in format string"
The use of <> in Fortran edit descriptors is non-standard, though widely implemented. You certainly can build edit descriptors from variables, the standard way is through an internal write, something like this (omitting declarations):
format_string = ''
write(format_string,'(a1,i0,a6)') 'A', file_label_end,'''_c.txt''' ! WARNING I haven't tested this
and then
write(output_filename,fmt=format_string) filename
But in your case this is not entirely necessary. You could try this instead
file_label_end = SCAN(filename, '.') - 1
WRITE (output_filename,'(a)') filename(1:file_label_end)//'_c.txt'
With the 'a' edit descriptor omitting a width means that all the characters in the expression will be written. You may want to declare
character(len=*), allocatable :: output_filename
if you haven't already done so.
The easiest is to use modern fortran
WRITE (output_filename,'(a)') trim(filename) // '_c.txt'
Otherwise I would write the number in the format string using a similar internal write.