sk8terg1rl wrote:
> Hi group, Happy Easter! :-)
>
> I've been trying to read a line in an input file that has a mix of
> characters & integers. The format can be assumed to be characters for
> 15 columns and a binary string of unknown/variable length.
>
> The format of the input file 'test.txt':
> |-CHARAC15-------|-----------INTEGER-----------.....
> Binary string = 010101010 ....
>
> The following test program fails:
> Program test_format
> Implicit None
>
> Integer:: buffer
> Integer, allocatable:: vector(:)
> Character:: a15*15
> buffer=1000
> Allocate (vector(buffer))
> Open (1,file='test.txt')
> Read (1,*) a15, vector(1:10)
> Print *, a15
> print *, vector(1:10)
>
> End program test_format
>
> Some questions...
> - If I change the Read statement to Read (1,'(a15,10000i1)') it works.
> However I want to read it in as free format if possible, so that if
> the binary string is longer than 10000 bits, my program won't cause
> problems.
It's not directly possible in free format because something like
010101 is an integer and there is no way for the processor to know
that you mean 6 "1 bit" numbers, rather than a 6 digit decimal
number. There are two general approaches to consider.
1) declare a huge character string, bigger than you will ever need
and "read" through it character by character.
something like
character (len=1000000000000000000) :: x !or maybe smaller ;)
x=' '
read(...) x
do i = 1,10000000000000000000000
if(x(I:I) == '1') vector(i) = 1
if(x(I:I) == '0') vector(i) = 0
if(x(I:I) == ' ') exit
enddo
here, I will be the actual length
2) use non advancing I/O and read each digit with an I1 format.
You'll need to add ADVANCE='NO' to the read. If you can't find
out about non-advancing I/O, ask here and several people will
explain it.
With either one, you'll need to make VECTOR be big enough before you start.
> - Similarly for writing out large arrays...I don't want to have to
> specify "Write (1,'(a15,10000i1)')" as arrays larger than 10000 would
> get truncated.
Formats revert when they come to their end and there are still
items in the I/o list. You could do something like
write (1, '(a15, 100i1, (15x,100i1)) title, vector
that will write out the title and first 100 digits one the first
line and then 15 blanks and the next 100 digits on the second and
third and ... nth line. It will use as many lines as necessary
and write out the odd number one the last line.
> - Is there an easy way to get the program to initially parse test.txt,
> look for the widest binary string length, and automatically allocate
> "buffer" to match that size?
No easy, if there are many lines you need to read them in one at a time
into a huge string and look for the longest line. you can probably do
something like
lentrim(x)-15
which will tell you how many digits there are on one line and then
find the max of this over all of the lines.
Hope this helps
Dick Hendrickson
>
> Thanks everyone,
> skate xx
>