2016-09-04 16 views
-4

我正在學習如何編程與FORTRAN90,我需要通過命令提示符從一個txt文件接收數據(類似的東西:
的Program.exe「<」 data.txt中) 。 在輸入txt文件我將永遠有一個單行,至少有6個數字,直到無窮大。如果數據是逐行寫入,它運行良好,但作爲單行我收到錯誤:「traceback:不可用,用-ftrace = frame編譯或-ftrace =完整的fortran運行時錯誤:結束文件」數據入口錯誤的Fortran

*注:我使用武力FORTRAN 2.0

我這裏是數據:

0 1 0.001 5 3 1 0 -9 3 

編輯:只是澄清:該代碼工作正常本身除了讀聲明,這是一個簡單的「r EAD *「。 我想知道如何從txt中讀取整個行,一旦入口將由promt命令以流方向進行。 (你可以在這裏看到更多關於:https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr=true)。 沒有必要閱讀代碼,我只是爲了知識而發佈它。

對於造成您的不便,我深表歉意。

這裏是迄今爲止代碼:

program bissecao 
implicit none 
integer::cont,int,e,k,intc,t1,t2,t3 
doubleprecision::ii,is,pre,prec,erro,somaa,somab,xn 
doubleprecision,dimension(:),allocatable::co 
t1=0 
t2=0 
t3=0 


                         ! print*,"insira um limite inf da funcao" 
read*,ii 
                         !print*,"insira o limite superior da func" 
read*,is 
                         ! print*,"insira a precisÆo admissivel" 
read*,pre 
                         if (erro<=0) then !elimina criterio de parada negativo ou zero 
                          Print*,"erro" 
                          go to 100 
                          end if 
                         !print*,"insira a qtd iteracoes admissiveis" 
read*,int 
                         !print*,"insira o grau da f(x)" 
read*,e 
                         if (e<=0) then ! elimina expoente negativo 
                          e=(e**2)**(0.5) 
                          end if 
allocate(co(e+1)) 
                         !print*, "insira os coeficientes na ordem:& 
                           ! &c1x^n+...+(cn-1)x^1+cnx^0" 
read(*,*)(co(k),k=e+1,1,-1) 


somab=2*pre 
intc=0 


     do while (intc<int.and.(somab**2)**0.5>pre.and.((is-ii)**2)**0.5>pre) 

      somab=0 
      somaa=0 
       xn =(ii+is)/2 

        do k=1,e+1,1 
         if (ii /=0) then 
          somaa=ii**(k-1)*co(k)+somaa 
         else 
         somaa=co(1) 
         end if 
     ! print*,"somaa",k,"=",somaa 
        end do 
        do k=1,(e+1),1 
         if (xn/=0) then 
         somab=xn**(k-1)*co(k)+somab 
         else 
         somab=co(1) 
         end if 
     !print*,"somab",k,"=",somab 
        end do 

       if ((somaa*somab)<0) then 
         is=xn 
       else if((somaa*somab)>0)then 
         ii=xn 
       else if ((somaa*somab)==0) then 
         xn=(ii+is)/2 
         go to 100 
       end if 
       intc =intc+1 
       prec=is-ii 
       if ((((is-ii)**2)**.5)< pre) then 
       t3=1 
       end if 
       if (((somab**2)**.5)< pre) then 
       t2=1. 
       end if 
       if (intc>=int) then 
       t1=1 
       end if 
     end do 
     somab=0 
         xn=(ii+is)/2 
        do k=1,(e+1),1 
         if (xn/=0) then 
         somab=xn**(k-1)*co(k)+somab 
         else 
         somab=co(1) 
         end if 
        end do 


100 write(*,'(A,F20.15,A,F20.15,A,A,F20.15,A,F20.15,A,I2)'),"I:[",ii,",",is,"]","raiz:",xn,"Fraiz:",somab,"Iteracoes:",intc 

end program !---------------------------------------------------------------------------- 
+4

看看你的帖子並問問你自己*我讓人們很容易閱讀我的代碼嗎?或者,直言:你發佈的東西是一團糟,而我,其中一個,甚至不會去嘗試閱讀它。 –

回答

0

在你的程序中,您使用的是 「表式輸入」(即,read *,read(*,*)

read *, ii 
read *, is 
read *, pre 
read *, int 
read *, e 
read *, (co(k), k = e+1, 1, -1) 

這意味着程序在每個read語句之後(通過忽略同一行中的任何剩餘數據)轉到數據文件的下一行。

0 
1 
0.001 
5 
3 
1 0 -9 3 

但現在你正試圖讀取包含只有一行輸入文件:那麼,如果數據文件(說「multi.dat」)由單獨的線(由OP的建議)程序工作(說「single.dat」)

0 1 0.001 5 3 1 0 -9 3 

在這種情況下,我們需要閱讀所有與單個read聲明的值(如果列表定向輸入要使用)。

這裏的一個細微之處是數組co的範圍取決於e,這也需要通過相同的read語句來讀取。一種解決方法可能是剛剛預分配co具有足夠大數量的元件(比如100)的和在一行讀出的數據,例如,

integer :: k 
allocate(co(100)) 
read *, ii, is, pre, int, e, (co(k), k = e+1, 1, -1) 

爲了完整起見,在這裏是一個測試程序您可以在其中選擇method = 1或2來讀取「multi.dat」或「single.dat」。

program main 
    implicit none 
    integer :: int, e, k, method 
    double precision :: ii, is, pre 
    double precision, allocatable :: co(:) 

    allocate(co(1000)) 

    method = 1 !! 1:multi-line-data, 2:single-line-data 

    if (method == 1) then 
     call system("cat multi.dat") 
     read*, ii 
     read*, is 
     read*, pre 
     read*, int 
     read*, e 
     read*, (co(k), k = e+1, 1, -1) 
    else 
     call system("cat single.dat") 
     read*, ii, is, pre, int, e, (co(k), k = e+1, 1, -1) 
    endif 

    print *, "Input data obtained:" 
    print *, "ii = ", ii 
    print *, "is = ", is 
    print *, "pre = ", pre 
    print *, "int = ", int 
    print *, "e = ", e 

    do k = 1, e+1 
     print *, "co(", k, ") = ", co(k) 
    enddo 
end program 

您可以通過從標準輸入輸入文件

./a.out < multi.dat (for method=1) 
./a.out < single.dat (for method=2) 

請注意,「multi.dat」也可以直接使用「<」讀。

+0

我學到了一些新東西......如果數據在文件中,我會以更傳統的方式打開文件並讀取文件,因爲我一直這樣做。 – Holmz

+1

我同意(我通常也這樣做),但有時從標準輸入(如一些用於模擬的小型實用工具)獲取輸入文件也很方便,以便輸入文件的名稱更加靈活。儘管如此,我認爲這些數據並不需要是一蹴而就的:) – roygvib