2017-04-01 83 views
0

有一个文件包括以下列格式行:如何从文件中读取和解析一行?

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

stringcharcharinteger

的文件需要被读取并存储在两个阵列中的第一个应该存储字符串和字符 a第二个应该存储整数。

这怎么办?


最初的尝试是here

1.连接成单个字符串,因为它们带有逗号和空格。


+0

整数保证占用这三列吗? –

+0

@VladimirF该整数至多为数字。 – Ziezi

回答

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 
+1

但我想对于这种工作,其他工具(python熊猫或excel-like工具??)可能会更容易使用... – roygvib

+0

很好的答案,谢谢!特别是通过补充意见的澄清。 – Ziezi

+1

很高兴,如果它的工作:)有关更多信息,这些网页可能是非常有用的http://stackoverflow.com/documentation/fortran/topics http://www.fortran90.org/index.html# http:// www。 cs.rpi.edu/~szymansk/OOF90/bugs.html – roygvib