2016-08-12 127 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