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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Fortran 95 Program Error 1

Status
Not open for further replies.

carltonlacey

Technical User
Oct 28, 2011
5
GB
Dear Fellow Members, 28/10/2011

I am presently trying to write a Fortran 95 program to

separate acids from a list of chemicals in a text file and

then write them to a second text file. The program first

matches the word "acid" and is then supposed to check

if the word preceding the word "acid" contains the letters

"ic" (For example Sulphuric Acid, Nitric Acid). If both

are true, then it should print the name of the acid on to

the second text file.

The problem is that it prints out the whole sentence

containing the name of the acid and also skips many other

acid names from the same paragraph. I am stuck as I can't

figure out where I have made errors in the code. I am

pasting below the code I have written. Can some body

please tell me where I am going wrong?

Thanks and regards

carltonlacey

Program Abs reader
c
character*80 line, dsn, tsave
character*1 reply
integer*4 i, we2, ws2, we1, ws1
logical chem
c
write(*,'(a,$)') 'Input file name:'
read(*,'(a)',end=21)dsn
open(unit=10,file=dsn,status='old')
open(unit=30,file='abscopy.txt',status='unknown')
c
12 read(10,'(a)',end=21)line
do k = 1,80
if (line(k:k).ne.' ')then
ws2=k
end if
do i=k+1,80
if(line(i:i).eq.' ')then
we2= i-1
chem = .false.
call chemical2(ws2,we2,chem,line)
if (chem) then
tsave=line(ws2:we2)
end if
we1=ws2-2
do j=we1,1
if(line(j:j).eq.' ')then
ws1=j+1
call chemical1(ws1,we1,tsave,line,ws2,we2,chem)
if (chem) then
write(30,'(a)')line(ws1:we1),tsave(ws2:we2)
c write(30,'(a)')
ws2=we2+2
goto 13
end if
end if
end do
end if
13 continue
end do
goto 12
end do
21 continue
stop
end
c This subroutine tells the program to record words that fit certain criteria.
c
subroutine chemical2(ws2,we2,chem,line)
character*80 line, tsave
integer*4 ws2, we2
logical chem
c
c check for 'acid' and record
do n=ws2,we2
if(line(n:n+3).eq.'acid')then
chem=.true.
return
end if
end do
return
end
c
c
subroutine chemical1(ws1,we1,tsave,line,ws2,we2,chem)
character*80 line,tsave
integer*4 ws1, we1, ws2, we2
logical chem
c
c check previous word has 'ic'
if(line(we1-1:we1).eq.'ic')then
chem=.true.
return
end if
return
end




 
Hi carltonlacey,
Please, post what is the input text file and what you wamt to utput.
 
Difficult to understand clearly your algorithm. It is easier for me to write my own version. I suppose only that the word before "Acid" (or "acid") is composed of letters and ends by "ic" as required.

Code:
      program absreader
      
      implicit none
     
      character*80 line, dsn
      integer i,k,first,last
     
      write(*,'(a)',advance='no') 'Input file name: '
      read(*,'(a)') dsn
      
      open(unit=10,file=dsn,status='old')
      open(unit=30,file='abscopy.txt',status='unknown')
     
      main:do
      
        read(10,'(a)',end=21) line
        
        k=1 ! position at the beginning of line
        
        do
        
          i=index(line(k:),'Acid') ! looking for the string Acid
          if(i == 0) i=index(line(k:),'acid')
          
          if(i==0) cycle main ! no more acid in the line
          
          k=k+i-1 ! starting position of Acid in the line
          
          ! looking for the first character before Acid
          
          do last=k-1,1,-1
            if(line(last:last) /= ' ') exit
          enddo
          
          if(line(max(1,last-1):last).eq.'ic') then
          
            ! the previous word ends with "ic" as required
            ! on needs to locate the beginning of that word
            
            do first=last-1,1,-1
              if(.not.is_a_letter(line(first:first))) exit
            enddo
            
            first=first+1
            write(30,'(3a)') line(first:last),' ','acid'
            
          endif
          
          k=k+4 ! skips the analyzed part
          
        enddo ! continue to scan the current line
        
      enddo main

  21  continue
  
      contains
      
      function is_a_letter(char) result(r)
      ! a simple function to test whether a character is a letter
      character,intent(in) :: char
      logical :: r
      if(char >= 'A' .AND. char <= 'Z') then
        r=.true.
        return
      endif
      if(char >= 'a' .AND. char <= 'z') then
        r=.true.
        return
      endif
      r=.false.
      end function
        
      end

Input file "chem.txt"

Code:
Sulphuric Acid, Nitric Acid, not an acid,
   acetylsalicylic Acid

Result file abscopy.txt :

Code:
Sulphuric acid
Nitric acid
acetylsalicylic acid


François Jacq
 
does it have to be Fortran? 'cause Fortran is a FORmula TRANslator, not the best at string manipulation, parser, spliter kind of language...this could probably be a 10 line python program.
 
FJacq, 29/10/2011

Thank you very much for your reply. I have tested your program on my file and it works fine. I have uploaded the text file that I am working on for you all to see. The first word that should be found from this file is "2,3-diamino-2,3-dideoxy-beta-D-mannuronic acids,". This has both an "s" and "," after the acid

I have a couple of more questions. I note that you are using a different version of Fortran than me ( I am using the Salford Plato 2 IDE). Please let me know how I can change the code so that I can find any words which contain "acid", for eg. sometimes there is a comma "," or a full stop "." after the word acid. Also plural like "acids".


Thanks and regards

carltonlacey
 
 http://www.mediafire.com/?pa46ln11iyaicp9
Dear Mikrom,

Thank you very much for your prompt reply to my posting. I have uploaded my input file. What I would like to do with this file is as follows:

Write all words containing Acid, acid, acids, Acids,from this file in to an output file. The whole name containing the acid must appear in the output file. Sometimes, the name will be immediately followed by a comma or a full stop, in which case the program should still be able to recognize the name and print it to the out put file.

There is a problem with my code and I would appreciate it if you could figure out where exactly it is.

Thanks and regards

carltonlacey
 
Dear salgerman,

Thank you very much for your prompt reply to my post.

Unfortunately, the rest of my program is in Fortran 95, so I can only work with this code. Also, though I have heard of Python, I have no idea of the language and would not have the foggiest on how to integrate it with the rest of my code or make changes to it, if needed. Anyway, it was a nice suggestion and I will try to learn more about Python.

Thanks and regards

carltonlacey.
 
If you want to look for more possible characters, you just have to modify slightly the function is_a_letter. Here is a version accepting "." and "," as well. But you should notice that there is a risk a confusion because "," might also used as delimiters between names.

Code:
      ...
      contains
      
      function is_a_letter(char) result(r)
      ! a simple function to test whether a character is a letter
      character,intent(in) :: char
      logical :: r
      if(char >= 'A' .AND. char <= 'Z') then
        r=.true.
        return
      endif
      if(char >= 'a' .AND. char <= 'z') then
        r=.true.
        return
      endif
      if(char == '.' .AND. char == ',') then
        r=.true.
        return
      endif
      r=.false.
      end function

      end program

About the compilers I use, they are all F95 compliant and I programmed in respecting the F95 norm in a form compatible together to the fix and free formats.

François Jacq
 
Dear FJacq,

I apologize for the late reply. I have tried out the new variation and everything works fine. I appreciate your taking the time to sort out my problem.

Once again thank you very much for your help and guidance.

Kind regards

Yours truly

carltonlacey
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top