2016-08-12 133 views
0

我需要讀取我的一個模擬器的輸出並存儲值。文件名是forces.dat,幷包含了類似的事情,如下所示:如何讀取混合文本文件並僅提取數字

# Forces  
# CofR  : (4.750000e-01 3.500000e-02 2.000000e-02) 
# Time  forces(pressure viscous porous) moment(pressure viscous porous) 
2.633022e-02 ((6.268858e-02 -1.468850e+01 1.542745e-20) (1.000906e-03 8.405854e-06 -5.657665e-17) (0.000000e+00 0.000000e+00 0.000000e+00)) ((-8.779466e-18 8.442993e-19 -3.225599e-03) (-2.082489e-18 4.435609e-18 -1.572485e-03) (0.000000e+00 0.000000e+00 0.000000e+00)) 
8.095238e-02 ((1.781333e-01 -1.468455e+01 -3.545427e-19) (2.362118e-03 2.014609e-05 1.691584e-16) (0.000000e+00 0.000000e+00 0.000000e+00)) ((-3.344781e-18 -5.448339e-19 2.227502e-02) (5.092628e-18 -3.538718e-18 -1.203074e-03) (0.000000e+00 0.000000e+00 0.000000e+00)) 
1.600000e-01 ((3.204471e-01 -1.467482e+01 -4.599174e-18) (6.936764e-03 1.303800e-04 4.836650e-17) (0.000000e+00 0.000000e+00 0.000000e+00)) ((-1.123589e-17 -4.344967e-19 5.591623e-02) (1.532415e-18 -1.345592e-18 -9.550750e-04) (0.000000e+00 0.000000e+00 0.000000e+00)) 

我想知道我應該怎麼寫一個Fortran子程序忽略第一個3線,然後讀取下一行數,然後將值的每一行。

回答

1

您可以使用此代碼段來記錄行號。根據您的要求和文件的性質,您可以獲取各個行的值並可以執行所需的操作。

string CurrentLine; 
int LastLineNumber; 
void NextLine() 
{ 
// using will make sure the file is closed 
using(System.IO.StreamReader file = new System.IO.StreamReader ("c:\\forces.dat")) 
{ 
    // Skip lines 
    for (int i=0;i<LastLineNumber;++i) 
     file.ReadLine(); 

    // Store your line 
    CurrentLine = file.ReadLine(); 
    LastLineNumber++; 
} 
} 

在上面的代碼,裏面for循環,你可以把你的基礎上,你想讀的行文件的處理邏輯。

+0

謝謝勞拉。它不是C代碼嗎?我現在需要一個fortran代碼。 – IGHA

+0

你沒有提到關於fortran的地方。可能你也可以用fortran同樣的邏輯 – Lara

0

雖然我認爲它更容易預處理通過一些命令行工具(如sed -e 's/(/ /g' -e 's/)/ /g' input.dat),我們也可以直接通過讀取每一行成一個長字符串,並刪除所有不必要的括號使用的Fortran文件:

program main 
    implicit none 
    integer, parameter :: mxline = 5000 !! choose appropriately 
    integer i, ios, finp, nl 
    character(500) str 
    real, save :: time(mxline) 
    real, dimension(3, mxline), save :: & 
      frc_pres, frc_visc, frc_poro, & 
      mom_pres, mom_visc, mom_poro 

    finp = 10 
    open(finp, file="input.dat", status="old") 

    nl = 0 
    do 
     read(finp, "(a)", iostat=ios) str 
     if (ios /= 0) exit 
     str = trim(adjustL(str)) 

     !! Skip comment or blank lines. 
     if (str(1:1) == "#" .or. str == "") cycle 

     !! Replace parentheses with space. 
     do i = 1, len_trim(str) 
      if (str(i:i) == "(" .or. str(i:i) == ")") str(i:i) = " " 
     enddo 

     !! Read data from the string. 
     nl = nl + 1 
     read(str, *) time(nl), & 
         frc_pres(:, nl), frc_visc(:, nl), frc_poro(:, nl), & 
         mom_pres(:, nl), mom_visc(:, nl), mom_poro(:, nl) 
    enddo 

    close(finp) 

    !! Check. 
    do i = 1, nl 
     print * 
     print *, "time = ", time(i) 
     print *, "frc_pres = ", frc_pres(:, i) 
     print *, "frc_visc = ", frc_visc(:, i) 
     print *, "frc_poro = ", frc_poro(:, i) 
     print *, "mom_pres = ", mom_pres(:, i) 
     print *, "mom_visc = ", mom_visc(:, i) 
     print *, "mom_poro = ", mom_poro(:, i) 
    enddo 

end program 

如果數據值可能變得非常大(例如1.0e100),請考慮使用雙精度實數,以免失去必要的精度。

+0

謝謝roygvib。它工作完美。雖然我寫了另一個程序,但是這個程序要快得多。 – IGHA