2016-08-12 4 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)) 

私は最初の3行を無視するようにFortranのサブルーチンを書き、その後、次の行数を読み、値すべき方法を知りたいです各行の

答えて

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

関連する問題