Как прочитать смешанный текстовый файл и извлечь только числа

Мне нужно прочитать вывод одного из моих симуляторов и сохранить значения. имя файла 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 строки, а затем читать количество следующих строк, а затем значения каждой строки.


person IGHA    schedule 12.08.2016    source источник


Ответы (2)


Вы можете использовать этот фрагмент, который будет отслеживать номера строк. В зависимости от ваших требований и характера файла вы можете получить значения соответствующих строк и выполнить необходимые действия.

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 вы можете поместить свою логику обработки файлов на основе строк, которые вы хотите прочитать.

person Lara    schedule 12.08.2016
comment
Спасибо, Лара. Разве это не C-код? Мне нужен код fortran в моей программе сейчас. - person IGHA; 12.08.2016
comment
у вас нигде не упоминается про фортран. Может быть, вы можете применить ту же логику и к фортрану - person Lara; 12.08.2016

Хотя я думаю, что проще предварительно обработать файл с помощью какого-либо инструмента командной строки (например, 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), рассмотрите возможность использования вещественных чисел двойной точности, чтобы не потерять необходимую точность.

person roygvib    schedule 12.08.2016
comment
Спасибо roygvib. Он работает идеально. Хотя я написал другую программу, но эта намного быстрее. - person IGHA; 19.08.2016