如何从文件中读取和解析一行?

时间:2017-04-01 15:16:11

标签: file parsing fortran

有一个由以下格式的行组成的文件:

John, D E       100
Bob, F I        200
Oli, G H       1500
...

一般来说:

  

stringchar char integer

需要读取文件并将其存储在两个数组中,第一个应存储字符串和字符 1 ,第二个应存储整数。

怎么可以这样做?

初步尝试here

1。用逗号和空格连接成单个字符串。功能

1 个答案:

答案 0 :(得分:1)

如果输入文件中的项目用空格或逗号分隔,我们可以使用列表导向的输入(fmt=*)来读取它们,如链接问题中的注释所示,这样

read (funit, [fmt =] *, iostat = ios) surname, first_name, second_name, consumption

其中“fmt =”部分是可选的。以下是链接页面中原始代码的略微修改版本(请参阅代码中的注释以获取更多详细信息):

module MyModule
    implicit none  !<-- this propagates to all routines in this module
contains

subroutine ReadFileIntoArrays (filename, name_arr, kWh_arr, ndata)

    character(*), intent(in) :: filename     !<-- an assumed-length string
    character(*), intent(out) :: name_arr(:) !<-- an array of assumed-length strings
    integer, intent(out) :: kWh_arr(:), ndata

    character :: first_name, second_name  !<-- a single char
    character(50) :: surname              !<-- a string of 50 chars
    integer :: consumption, funit, ios, idx

    funit = 10  ! use >= 10 (or open( newunit=funit, ... ) for recent compilers)
    open (funit, file = filename, status = 'old')

    idx = 0
    do
        read (funit, fmt = *, iostat = ios) &   !<-- "&" means line continuation
                surname, first_name, second_name, consumption

        ! "fmt = *" (list-directed input) tells the compiler
        ! to use whitespaces/commas as delimiters.

        if (ios > 0) then
            print *, "Wrong input format!" ; exit
        else if (ios < 0) then
            print *, "finished reading data." ; exit
        else
            idx = idx + 1
            if (idx > size( name_arr )) stop "size of name_arr(:) too small"

            ! trim() chops trailing spaces in a string
            name_arr( idx ) = trim(surname)//','//first_name//'.'//second_name//'.'
            kWh_arr( idx ) = consumption
        end if
    end do
    ndata = idx

    close (funit)
end subroutine

end module

program MyMain
    use MyModule
    implicit none
    integer :: consumption( 10 ), ndata, idx
    character(50) :: names( 10 )  !<-- an array of size 10 (each element = 50-char string)
    character(200) :: filename    !<-- a string of 200 chars

    filename = "clients.txt"
    names = ""
    consumption = 0

    call ReadFileIntoArrays (filename, names, consumption, ndata)

    print "(2a20)", "name", "consumption"
    do idx = 1, ndata
        print "(a20,i20)", trim( names( idx ) ), consumption( idx )
    enddo
end program

然后,根据问题中的输入,输出变为

 finished reading data.
                name         consumption
           John,D.E.                 100
            Bob,F.I.                 200
            Oli,G.H.                1500