置頂

我的 VPython 教學文件 (HackMD 版本)

VPython 教學文件目錄 安裝及測試 基本語法 等速度直線運動 自由落下 終端速度 水平抛射 使用For迴圈計算水平抛射資料 斜向抛射 圓周運動 簡諧運動 單擺 木塊彈簧系統分離 重力及簡諧 行星運動 相疊木塊 雙重簡諧運動 一維彈性碰撞 ...

熱門文章

2021年7月31日 星期六

安裝 GFortran 使用 Fortran 程式讀取、寫入 csv 檔

作者:王一哲
日期:2021/7/31


前言


我之前幾乎沒有寫過 Fortran,這次為了幫某人擺脫需要花錢購買的 Visual Fortran,我只好從零開始學 Fortran,並且試試看是否能用 GFortran 編譯他們實驗室需要的程式碼,由 csv 檔讀取資料經過一些運算後再儲存成另一個 csv 檔,以下是我測試的筆記。


於 Ubuntu 安裝 GFortran


我使用的作業系統是 Ubuntu 20.04.2 LTS,只要在文字界面中執行以下指令即可安裝 GFortran。
sudo apt install gfortran-10

安裝完畢之後可以用以下指令查詢安裝的版本,我安裝的版本是 10.3.0。
gfortran-10 --version

建立一個測試用的資料夾,於資料夾中用文字編輯器將以下內容儲存成 hello.f95。
program hello
    write(*, *) 'Hello World!'
    write(*, *) '哈囉世界!'
stop
end program hello

用以下指令將 hello.f95 編譯成執行檔再執行檔案。
gfortran-10 -o hello hello.f95
./hello

如果螢幕輸出以下文字就成功了。
 Hello World!
 哈囉世界!



於 Windows 10 安裝 GFortran


我使用的作業系統是 Windows 10 家用版。安裝步驟主要是參考這篇文章 Installation of GFortran in Windows 10。先安裝 mingw-w64,目前最新的版本是 msys2-x86_64-20210725.exe,下載連結在此。安裝完成之後開啟 MSYS2 MinGW 64-bit。
MSYS2


輸入以下指令更新軟體列表、安裝 GFortran。
pacman -Syu
pacman -Su gcc-fortran

輸入以下指令查詢安裝好的 GFortran 版本。
gfortran.exe --version

我安裝的是 10.2.0 版。用 pwd 查詢路徑,看起來是在 /home/[UserName] 底下,實際上的路徑是
C:\msys64\home\[UserName]

接著用 Hello World! 測試一下。
於 Windows 10 測試 GFortran



使用 Fortran 程式讀取、寫入 csv 檔


這次的目標是要在執行程式時於後方加上輸入、輸出檔名,由輸入的 csv 檔讀取資料,再將資料寫到輸出的 csv 檔,主要是參考這兩個網頁的內容:Passing command line argumentsTEK-TIPS.COM: Help with .csv。假設輸入檔名為 input.csv,內容如下,第一行開頭的 ! 是為了在讀取資料時忽略此行而加上的記號。
!h(m),t(s),errt(s)
2,0.65,0.01
4,0.89,0.01
6,1.11,0.01
8,1.27,0.01
10,1.42,0.01
12,1.57,0.01
14,1.71,0.01
16,1.79,0.01
18,1.92,0.01
20,2.03,0.01

以下是我測試成功的程式碼。
program fileIO

    implicit none                     ! 不使用預設變數名稱及種類對應關係
    character(20) :: inputfile        ! 輸入檔名用的變數
    character(20) :: outputfile       ! 輸出檔名用的變數
    integer :: flag1, flag2, line_num ! 檔案狀態1、2, 行號 
    character(80) :: line             ! 讀取的整行資料
    real :: h, t, t2, errt            ! 儲存資料的變數

    ! 檢查輸入的參數是否為2個
    if(command_argument_count().NE.2) then
        write(*,*) 'Error! Please enter the input and output file names.'
        stop
    end if

    ! 由輸入的參數取得輸入、輸出檔名
    call get_command_argument(1, inputfile)
    call get_command_argument(2, outputfile)

    write(*,*) 'The input file name is: ', inputfile
    write(*,*) 'The output file name is: ', outputfile

    ! 由 inputfile 讀取資料, 準備寫入資料至 outputfile
    open(3, file=inputfile, status='old', action='read', iostat=flag1)
    open(4, file=outputfile, action='write', iostat=flag2)

    ! 檢查是否能開啟檔案
    if(flag1 .NE. 0) then
        write(*, *) 'Cannot open input file!'
        go to 99
    end if

    if(flag2 .NE. 0) then
        write(*, *) 'Cannot open output file!'
        go to 99
    end if

    ! 於 outputfile 寫入欄位標題
    write(4, *) '!h(m),t(s),t2(s2),errt(s)'

    line_num = 0
    do 
        ! 讀取整行資料並存入 line
        read(3, '(A)', end=99, iostat=flag1) line
        ! 若 flag1 不等於 0 則跳到 99 continue        
        if(flag1 .NE. 0) then
            write(*, *) 'Cannot read data!'
            go to 99
        end if
        ! 若 line 的開頭為 '!' 則不做任何事
        if(adjustl(trim(line(1:1))) .EQ. '!') then
            cycle
        end if
        ! 將 line 的資料分別存入 h, t, errt, 計算 t^2, 存入 outputfile
        read(line, *) h, t, errt
        t2 = t**2        
        write(*, *) 'line ', line_num, ': ', h, t, t2, errt
        line_num = line_num + 1
        write(4, *) h, ',', t, ',', t2, ',', errt
    end do

    99 continue
    close(3)
    close(4)

stop
end program fileIO

假設檔名是 fileIO.f95,在 Ubuntu 可以使用以下指令編譯程式。
gfortran-10 -o fileIO fileIO.f95

在 Windows 10 可以使用以下指令編譯程式。
gfortran.exe -o fileIO fileIO.f95

使用以下指令執行程式。
./fileIO input.csv output.csv

於文字界面輸出以下的內容。
 The input file name is: input.csv           
 The output file name is: output.csv          
 line            0 :    2.00000000      0.649999976      0.422499955       9.99999978E-03
 line            1 :    4.00000000      0.889999986      0.792099953       9.99999978E-03
 line            2 :    6.00000000       1.11000001       1.23210001       9.99999978E-03
 line            3 :    8.00000000       1.26999998       1.61289990       9.99999978E-03
 line            4 :    10.0000000       1.41999996       2.01639986       9.99999978E-03
 line            5 :    12.0000000       1.57000005       2.46490026       9.99999978E-03
 line            6 :    14.0000000       1.71000004       2.92410016       9.99999978E-03
 line            7 :    16.0000000       1.78999996       3.20409989       9.99999978E-03
 line            8 :    18.0000000       1.91999996       3.68639994       9.99999978E-03
 line            9 :    20.0000000       2.02999997       4.12089968       9.99999978E-03

於 Windows 10 測試 fileIO 程式碼


輸出的 csv 檔如下,看來應該有達到我要的效果。
 !h(m),t(s),t2(s2),errt(s)
   2.00000000     ,  0.649999976     ,  0.422499955     ,   9.99999978E-03
   4.00000000     ,  0.889999986     ,  0.792099953     ,   9.99999978E-03
   6.00000000     ,   1.11000001     ,   1.23210001     ,   9.99999978E-03
   8.00000000     ,   1.26999998     ,   1.61289990     ,   9.99999978E-03
   10.0000000     ,   1.41999996     ,   2.01639986     ,   9.99999978E-03
   12.0000000     ,   1.57000005     ,   2.46490026     ,   9.99999978E-03
   14.0000000     ,   1.71000004     ,   2.92410016     ,   9.99999978E-03
   16.0000000     ,   1.78999996     ,   3.20409989     ,   9.99999978E-03
   18.0000000     ,   1.91999996     ,   3.68639994     ,   9.99999978E-03
   20.0000000     ,   2.02999997     ,   4.12089968     ,   9.99999978E-03



結語


由於 Fortran 的語法與 Python、C、C++ 差異很大,寫起來感覺相當奇怪。接下來還要再修改他們實驗室以前的程式碼,其中一部分還是採用 Fortran 77 的語法撰寫,要修改成新版 GFotrtan 可以接受的語法才行,好像還有不少的麻煩要解決。


參考資料


  1. gfortran — the GNU Fortran compiler, part of GCC
  2. Installation of GFortran in Windows 10
  3. mingw-w64
  4. Passing command line arguments
  5. TEK-TIPS.COM: Help with .csv




HackMD 版本連結:https://hackmd.io/@yizhewang/Sk5vTFMyK

沒有留言:

張貼留言