Read the free format without first

In the given file entry, I need to first read the first two integer elements, and then the rest of the line (a large number of real elements), since the purpose depends on the first 2. Suppose that the format of the first two integer elements is not very well defined.

The best way to solve the problem might be something:

read(unitfile, "(I0,I0)", advance='no') ii, jj read(unitfile,*) aa(ii,jj,:) 

But it seems to me that the specification "(I0)" is not allowed in gfortran.

Basically, a file read in a unitfile might look something like this:

 0 0 <floats> 0 10 <floats> 10 0 <floats> 100 0 <floats> 100 100 <floats> 

which is hard to read with any fortrans formatted field format specification.

Is there any other way around this problem, apparently trivial?

+6
source share
2 answers

This applies string manipulation to get individual components separated by spaces ' ' and / or tabs ( char(9) ):

 program test implicit none character(len=256) :: string, substring integer :: ii, jj, unitfile, stat, posBT(2), pos real, allocatable :: a(:) open(file='in.txt', newunit=unitfile, status='old' ) read(unitfile,'(a)') string ! Crop whitespaces string = adjustl(trim(string)) ! Get first part: posBT(1) = index(string,' ') ! Blank posBT(2) = index(string,char(9)) ! Tab pos = minval( posBT, posBT > 0 ) substring = string(1:pos) string = adjustl(string(pos+1:)) read(substring,*) ii ! Get second part: posBT(1) = index(string,' ') ! Blank posBT(2) = index(string,char(9)) ! Tab pos = minval( posBT, posBT > 0 ) substring = string(1:pos) string = adjustl(string(pos+1:)) read(substring,*) jj ! Do stuff allocate( a(ii+jj), stat=stat ) if (stat/=0) stop 'Cannot allocate memory' read(string,*) a print *,a ! Clean-up close(unitfile) deallocate(a) end program 

For the in.txt file as:

 1 2 3.0 4.0 5.0 

The result is

 ./a.out 3.00000000 4.00000000 5.00000000 

NOTE. This is just a quick and easy example, tailor it to your needs.

+3
source

[This answer has been significantly revised: the original was unsafe. Thanks to IanH for pointing this out.]

I usually try to avoid formatting the input, which is not a list, when I can afford it. There is already an answer with parsing strings for great generality, but I will offer some suggestions for easier setup.

When you are relaxed, trusting input, for example, when it's just formatting that is a bit complicated (or you are happy to leave it to check the boundaries of your compilers), you can come close to your example with

 read(unitfile, *) ii, jj, aa(ii, jj, :) 

Alternatively, if the section of the array is more complex than specified directly by the first two columns, it can be an expression or even functions

 read(unitfile, *) ii, jj, aa(fi(ii,jj), fj(ii,jj), :fn(ii,jj)) 

with pure integer function fi(ii,jj) etc. There is even some possibility of having a range check in these functions (for example, returning a partition of size 0).

In a more general case, but remaining in the list, you can use a buffer for real variables

 read(unitfile, *) ii, jj, buffer(:) ! Or ... buffer(:fn(ii,jj)) ! Validate ii and jj before attempting to access aa with them aa(.., .., :) = buffer 

where the buffer is a suitable size.

Your first approach considered assumes that you have some reasonable idea of ​​the structure of the strings, including length, but when the number of reals is unknown from ii and jj , or when the type (and reading polymorphism isn 't allowed) is unknown, then everything really becomes complicated. In addition, if you are very sensitive to data entry verification or even provide meaningful detailed user feedback with an error, this is not optimal.

Finally, iostat helps.

+3
source

All Articles