Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to skip data while reading a text file?

Status
Not open for further replies.
Hi all,

I'm upgrading a legacy f77 code to f90 standards. I'm trying to make some of the global arrays as dynamic arrays so that at a later stage it would be easier for me to parallelize whole application.
Coming to my problem, I need to read some numbers from a text file so that I can allocate (just enough) memory to the multidimensional arrays. However, while reading the input text file I need to skip say 'n' real numbers and then resume reading. These real numbers span several records (=lines) in the input text file and the number of real numbers per record is not constant [sad].
In summary, I know how many real numbers I've to skip, but I do not know in how many records these numbers span.

Ex:
Input.data
Code:
3 3 3
1.23445 0.2345235 0.345234 0.123425235 0.12343245
0.31415927 1.23445 0.2345235 0.345234 0.123425235 0.12343245 
0.31415927 1.23445 0.2345235 
0.31415927 1.23445 0.2345235 0.2345235 
0.123 0.3245 0.74565355 4.34623431 56.2352354
3
33
3
33
12
6

I have to read first line and then skip 23 real numbers and then again start reading from line 7.
I currently have a code which works but it is not efficient,
My current code looks like this

Code:
[COLOR=gray]!Start reading the data from file, UNIT=16[/color]
[b]read[/b](16,*) i, j, k
[COLOR=gray]!I want to Skip reading data to dummy x(:,:,:) array[/color]
[b]read[/b] (16,*) (((x(ii,jj,kk),ii=1,i),jj=1,j),kk=1,k)
[COLOR=gray]! Resume reading[/color]
[b]read[/b](16,*) num

It would be great if someone could share there ideas or solutions.

cheers!
Prashanth
 
The number of real number in the above example are 23, but it should be 27. Kindly excuse the mistake.
 
27? instead of 23? Good thing I had copied to sample input file from the physicsforum!

You know what would help a lot? If the numbers had the exact same format...then, we can read one number at a time, no matter which line they are, and count up to 27, like this:

Code:
program skip
  integer i, j, k, n, nmax
  real dummy
  character*30 str
 
  read(*,*) i, j, k
  nmax = i*j*k
 
  n = 0
  do
    read(*,'(f11.8)', advance='NO', eor=100) dummy
    n = n+1
    write(*,*) 'n = ', n , '   dummy= ', dummy
    if (n == nmax) exit
    100 continue
  end do 
  read(*,*) j ; write(*,*) j 
  read(*,*) j ; write(*,*) j 
  read(*,*) j ; write(*,*) j 
  read(*,*) j ; write(*,*) j 
  read(*,*) j ; write(*,*) j 
end program skip

Compile this program and run it as follows: "skip < inputfile". See what it does and see if you can work with that...if you have control over how your input file is written, I would go ahead and make it so that it writes the inputfile as follows:

Code:
3 3 3
 1.23445000 0.23452350 0.34523400 0.12342523 0.12343245
 0.31415927 1.23445000 0.23452350 0.34523400 0.12342523 0.12343245 
 0.31415927 1.23445000 0.23452350 
 0.31415927 1.23445000 0.23452350 0.23452350
 0.12300000 0.32450000 0.74565355 4.34623431 5.23523540
 0.31415927 1.23445000 0.23452350 0.23452350
3
33
3
33
12
6
 
In cases like this, I have been using 'sed' (thanks to mikrom) to delete the lines containing '.' (in real numbers). The command is

Code:
sed '/\./d' old_file > new_file

You can use it in F90 as follows

Code:
program using_sed

  implicit none

  character(*), parameter :: sed_cmd = "sed '/\./d' old_file > new_file"
  integer                 :: sed_cmd_stat

  sed_cmd_stat = system (sed_cmd)

end program using_sed

where I assume that you have your data in 'old_file' and the new data without the real numbers wil be dumped in 'new_file'. Now you can read the data from the new file.


Gordon Shumway
 
dear Slagerman and melmacianalf, thanks for your suggestions. They are really useful. But I prefered the solution I got from physics forum. As I have very little changes to make.

For the completness of the thread, the below code shows the solution I used

Code:
Integer:: i, j, k, ii, jj, kk, num
Real, Allocatable, Dimension(:,:,:):: x 
Real:: Skip
!Start reading the data from file, UNIT=16
read(16,*) i, j, k
!Skip =dummy 
read (16,*) (((Skip,ii=1,i),jj=1,j),kk=1,k)
! Resume reading
read(16,*) num
 
I know I am a little bit late, but Gordon's idea
to delete the lines containing '.' (in real numbers)
would transform to a simple fortran code like

Code:
character*100 cBuffer
integer i, j, k, num
integer iPos, iEnd
open (unit = 16, file = input.txt)
read (16, * )i, j, k
do
    read (16, '(a100)', iostat = iEnd) cBuffer
    if (iEnd .ne. 0) exit 
    iPos = index (cBuffer, '.')
    if (iPos .ne. 0)  cycle
    read (cBuffer, *) num 
enddo
....

Just a few cents more.

Norbert


The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true.
 
I don't want to spend more time on this...I don't like when people post in two or more forums at the same time and waste multiple people's time in two different forums...as you see, the OP got his answer from the physicsforum...

...let's just wait to see if he/she comes around...I didn't think the answer from the physicsforum works...but maybe he/she will go back to whomever gave the answer...
 

I thank everyone for sparing their valuable time to answer my question. And kindly excuse if anyone feels that I've wasted their time by posting the same question in an another forum.
And the solution which I used works just as expected.
 
ok, thanks for reporting.
 
salgerman said:
I don't like when people post in two or more forums at the same time and waste multiple people's time in two different forums

I see nothing wrong in it. It is very common for someone who consults a forum for the first time to post the same question in many forums.

Gordon Shumway
 
Hi everyone,
i got a similar problem with f95... I have some trouble adapting an existing fortran code for my application.

In the following Module I am optimizing a value for two planes ( i = iplan one&two).
In order to do that, I need to assign ten certain values from an external inp. file for each plane.

I have two loops, the first one selecting iplan one, respectively two.
In this loop is the second one, which is supposed to read in value one (dcp(i,kl)) to ten.
One value for each run in the secon loop. That means each plane is assign with ten optimization runs, and each run with a certain value.

My problem is, that: read (iread,*) dcp(i,kl) doesn´t work. The read command is linked to
the correct variable in the external inp. file, but I think that there is something wrong with the declaration
of dcp(i,kl)?

Is there anyone who can help me with that problem?

Code:
! note: module inout for iread
    use inout
    integer :: kl, i, iplan, nscwmi=100, determdcp
    real :: xnscwmi, dcp(2,10), fractionvor
    dimension dcp(i,kl)

!for iplan=1 & iplan=2; nscwmi from differnet module 
    [B]i = 1,iplan[/B]
        xnscwmi = nscwmi
! determdcp from external inp with determdcp=1
        read(iread,*) determdcp
        if (determsp .eq. 1) go to 501
    continue

    501
    do 502 kl=1, 10
       READ (iread,*)[B][COLOR="Red"]dcp(i,kl)[/COLOR][/B]

        fractionvor = xnswmi
        xnscwmi = fractionvor/10

        ai   = xnscwmi*d(i,kl)+0.75
        imax = int(ai)
        ..
        ....
        b0(i) = 0.
        a0(i) = imax
        a1 (i)    = a1(i)+ a0(i)


Thanks!
 
I do not see neither an assignment of a value to iRead nor an open-Statement to connect a file to this unit.

And I do not understand the statement

i= 1,nPlan


Norbert

The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true.
 
The open statement and iread is done in another module and is working well....
The code above is just a short excerpt from a larger program code Iam using and the new values are supposed to improve the optimization and to minimize inaccuracy!
Since this is the first time working with fortran I am having hard times to program this loop and to declare values to the variable in this loop.
Regarding i=1, iplan, is supposed to to do this procedure for all planes/areas.
Sorry, I hope my explanation makes sense english isn´t my first tongue!
 
granbycools

if your compiler accepts this statement i = 1,iplan without producing an error, then you are using a younger version of Fortran than f95, which I am not familiar with.

As far as I understand your problem, you want to perform your loop 502 once for each value of i. If so, you should nest your loops like this

Code:
...
...
do i = 1, iPlan                   ! this is beginning of loop 501
   xnscwmi = nscwmi
   read (iread, *) determdcp
   do kl = 1, 10                  ! your loop 502
      read ....
      .....
   enddo                          ! end of loop 502
enddo                             ! end of loop 501
...
...

Norbert



The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top