INTELLIGENT WORK FORUMS FOR COMPUTER PROFESSIONALS
Come Join Us!
Are you a Computer / IT professional? Join Tek-Tips now!
- Talk With Other Members
- Be Notified Of Responses
To Your Posts
- Keyword Search
- One-Click Access To Your
Favorite Forums
- Automated Signatures
On Your Posts
- Best Of All, It's Free!
*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.
Partner With Us!
"Best Of Breed" Forums Add Stickiness To Your Site

(Download This Button Today!)
Feedback
"...I think the site is just incredible....I am learning more here than anywhere else before and am looking forward to being able to help someone .... this is my idea of what the Internet is supposed to do..."
Geography
Where in the world do Tek-Tips members come from?
|
Reading a text file without knowing the number of columns of data in Fortran 77.
|
|
|
ARR86 (Programmer) |
12 Jul 12 6:23 |
Hello All
I want to read a file that can contain different number of columns of data everytime in Fortran 77. i.e. I dont know the number of columns beforehand.If I know the number of columns,I can read the file like this way
SUBROUTINE varread(TNo,X,Y,Z,VARL)
IMPLICIT NONE
INTEGER NMAX
PARAMETER(NMAX=10000)
Integer N(NMAX),i,j,TNo
double precision X(NMAX),Y(NMAX),Z(NMAX),VARL(NMAX)
OPEN(35,file='exp1.txt')
j = 0
DO WHILE(.true.)
j = j+1
READ(35,600,END=900) N(j),X(j),Y(j),Z(j),VARL(j)
600 FORMAT(I4,1x,E16.7,1x,E16.7,1x,E16.7,1x,E11.4)
END DO
900 continue
TNo = j-1
CLOSE(35)
RETURN
END
In this file exp1.txt,I know that i will always have five columns of data namely N,X,Y,Z,VARL.So I read them easily using the format statement.
But in the file i want to read i know that it can have large number of columns but not how many.
I dont want to store the data in say 50 different variables.Is there a way to read the entire file as an array?.
Can somebody help me read the data?.
Regards
Anbazhagan.
|
|
Hmmm,
what makes you think that you are using Fortran77 ? At least the statement
DO WHILE(.true.)
is not a standard Fortran77 statement. The reason why I ask this is, that with Fortran 90/95 or later there is a chance to solve this problem, in Fortran77 I think not.
But to carry on, you should specify what you know about the file to read.
Do you know which datatypes it contains and their sequence if not uniform ?
Do you know the delimiter that is used to seperate the data ?
Do you know the length of one record of this file ?
Do all records of one given file have the same format as the first ?
The procedure I would propose is something like this
- define an allocatable array of the type you want to read from the file, maybe you a derived datatype is needed
- read one record into a string variable of sufficient length
- check how many delimiters occur in this string to the end of data
- allocate the number of elements in the array to the number of delimiters + 1
- read this array from the string.
- select and save the data that you are interested in from the array.
- continue reading the following records or redefine the number of elements to the array depending if the format changes from line to line or not.
Norbert
The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true. |
|
Just last week, I found myself in a similar boat. This is what was good enough for my application as far as finding out how many columns of data a particular line had...a function that returns the number of items in a line.
CODE! number of space-separated items in a line
integer function nitems(line)
character line*(*)
logical back
integer length
back = .true.
length = len_trim(line)
k = index(line(1:length), ' ', back)
if (k == 0) then
nitems = 0
return
end if
nitems = 1
do
! starting with the right most blank space,
! look for the next non-space character down
! indicating there is another item in the line
do
if (k <= 0) exit
if (line(k:k) == ' ') then
k = k - 1
cycle
else
nitems = nitems + 1
exit
end if
end do
! once a non-space character is found,
! skip all adjacent non-space character
do
if ( k<=0 ) exit
if (line(k:k) /= ' ') then
k = k - 1
cycle
end if
exit
end do
if (k <= 0) exit
end do
end function nitems
It is understood that you are reading the input file one line at a time and that is the string being passed to the function. |
|
|
ArkM (IS/IT--Management) |
13 Jul 12 2:25 |
My 2 cents:
CODEinteger function ntokens(line)
character,intent(in):: line*(*)
integer i, n, toks
i = 1;
n = len_trim(line)
toks = 0
ntokens = 0
do while(i <= n)
do while(line(i:i) == ' ')
i = i + 1
if (n < i) return
enddo
toks = toks + 1
ntokens = toks
do
i = i + 1
if (n < i) return
if (line(i:i) == ' ') exit
enddo
enddo
end function ntokens
|
|
|
ARR86 (Programmer) |
30 Jul 12 15:53 |
Hi
Thank you all for the replies. I was busy with my exams that is why i could not thank you earlier.
The file i want to read contains real data with two spaces as delimiter.
Once i find the number of columns in the file,how can i read and store it in a array?. What syntax of the format statement should i use?.Also it would be really helpful if you could tell me how to write the large columns of data to a file?. I don't have much knowledge in FORTRAN.It would be really helpful if you could help me out.
Regards
Anbazhgan.
|
|
It would be really helpful if you studied a little bit of fortran; otherwise, you are going to need more help on the next step. This thing you are asking is one of the most basic stuff...you should know this much.
|
|
|
ARR86 (Programmer) |
30 Jul 12 17:05 |
I think my earlier comment was misunderstood.The thing is i am transferring the code from matlab to fortran. I don't have problem in the logic part which is 90% moved to fortran. I am having problem in reading and writing the data, especially multidimensional array. I dont have any issues in reading and writing single columns of data such as XPOS(1000,1) etc in the post above. If XPOS is XPOS(1000,60),how to write it to a file?.I am using the statements below but it outputs in the wrong way.
No=60
NDIV=1000
OPEN(55,file='wv_num.txt')
DO J=1,No
WRITE(55,485),(XPOS(I,J),I=1,NDIV)
485 FORMAT(60(I4))
ENDDO
CLOSE(55)
And if a file has say 60 columns of data,how one should read it? Is it possible to store them in a single multidimensional array or should i use 60 separate variables in the read statement?
Regards
Anbazahgan. |
|
Now you are talking...I can see the problem, too...you have your dimensions 'swapped'...
Your format statement is set to write 60 numbers in a row (horizontally) but you are asking it to write 1000! (NDIV)
I think your code needs to look like this:
No=60
NDIV=1000
OPEN(55,file='wv_num.txt')
DO I=1,NDIV
WRITE(55,485),(XPOS(I,J),J=1,No)
485 FORMAT(60(I4))
ENDDO
CLOSE(55)
Of course, I just assumed that your XPOS matrix is 1000x60.
The point is that the number in the implicit loop and the multiplier in the format statement need to match.
If you matrix is 60x1000, then, clearly you need format(1000(I4))
|
|
|
 |
|