主题:[讨论]关于fortran读取各行长度不一格式不一具体行数不知数据文件的思考
shenjinggege
[专家分:3260] 发布于 2009-12-06 10:16:00
iwanfly网友曾在一段时间前发过贴探讨过这个问题
http://bbs.pfan.cn/post-312402.html
当时思路不是很清晰
现思考结果如下,虽然比较麻烦,但最终还是解决了读取数据的问题,前提是知道每行最大的数据个数,比如7个。
不知道论坛上的网友是否有更好的方法,不吝赐教。
测试数据如下:
12 89 77
12 999 878 777
398 789 765 98 765
78 89
12 89 77
12 999 878 777
398 789 765 98 765
。。。。
总共78144行。大概需要5,6秒时间把数据全部读进。
program main
implicit none
integer,allocatable :: int_array(:,:),temp_array(:,:)
integer :: count,length,step,i,ierr
character*256 :: str_one_record
open(100,file='data.txt')
count=0
step=100000
length=step
allocate(int_array(length,7))
int_array=0
do while(.not. eof(100))
count=count+1
loop1: do i=7,1,-1
read(100,'(A)',advance='no',eor=168) str_one_record
168 read(str_one_record,*,end=999) int_array(count,1:i)
exit loop1
999 backspace 100
int_array(count,1:i)=0
end do loop1
if(mod(count,step)==0) then
allocate(temp_array(length,7))
temp_array=0
temp_array=int_array
deallocate(int_array)
length=length+step
allocate(int_array(length,7))
int_array=0
int_array(1:length-step,:)=temp_array
deallocate(temp_array)
end if
end do
allocate(temp_array(length,7))
temp_array=0
temp_array=int_array
deallocate(int_array)
allocate(int_array(count,7))
int_array=0
int_array(1:count,:)=temp_array(1:count,:)
deallocate(temp_array)
!下面处理int_array中数据
deallocate(int_array)
close(100)
pause
end program main
回复列表 (共15个回复)
沙发
aliouying [专家分:1150] 发布于 2009-12-06 14:31:00
shenjinggege相当具有钻研精神,强烈要求加入石头的群:2338021
板凳
shenjinggege [专家分:3260] 发布于 2009-12-06 14:36:00
[quote]shenjinggege相当具有钻研精神,强烈要求加入石头的群:2338021[/quote]
申请了
3 楼
cgl_lgs [专家分:21040] 发布于 2009-12-07 14:15:00
Visual Fortran打开文件有另外的一种方法,不知道是不是FORTRAN通用的。
默认情况下打开的文本文件都是List,而设置了那个后,就可以一个一个地读(它不会自动到下一行的)
4 楼
臭石头雪球 [专家分:23030] 发布于 2009-12-07 15:07:00
我是用那个 GetDataN
首先用字符串读入,再调用这个函数,得到包含的数据个数。
再读取。
Integer Function GetDataN( cStr )
Implicit None
Character*(*) , Intent( IN ) :: cStr
Integer :: k
GetDataN = 0
If((cStr(1:1)/=" ".and.cStr(1:1)/=" ").and. &
(cStr(2:2)==" ".or.cStr(2:2)==" ".or.cStr(2:3)==" ")) then
GetDataN = GetDataN + 1
End If
do k = 2 , Len( Trim( cStr ) ) - 2
If((cStr(k:k)/=" ".and.cStr(k:k)/=" ".and.cStr(k-1:k)/=" ").and. &
(cStr(k+1:k+1)==" ".or.cStr(k+1:k+1)==" ".or.cStr(k+1:k+2)==" ")) then
GetDataN = GetDataN + 1
End If
end do
GetDataN = GetDataN + 1
End Function GetDataN
5 楼
asymptotic [专家分:16630] 发布于 2009-12-08 01:25:00
臭石头雪球 网友给的算法,当空格不定时,是不是“歇菜”了呢?
6 楼
asymptotic [专家分:16630] 发布于 2009-12-08 01:29:00
! ReadIrregularDataFile.f90
!
! written by Zeng Zhuo-Quan
!
! date: 2009 - 12 - 08
subroutine DataNo(str, ND)
implicit none
character(len = *), intent(in):: str
integer, intent(out):: ND
! *** *** *** *** *** immediate variable *** *** *** *** ***
logical:: LFT
character(len = 1):: ch
integer:: iL ! for loop
character(len = len(str)):: cstr
integer:: str_len
cstr = adjustL( str )
ND = 0
str_len = len_trim(cstr)
IF ( str_len > 0 ) THEN
LFT = .true.
Do iL = 1, str_len, 1
ch = cstr(iL : iL)
If ( (ch /= " ") .and. LFT ) Then
ND = ND + 1
LFT = .false.
Else If ( (ch == " ") .and. (.not. LFT) ) Then
LFT = .true.
End If !
End Do
END IF ! str_len > 0
return
end subroutine
7 楼
asymptotic [专家分:16630] 发布于 2009-12-08 01:31:00
! ReadIrregularDataFile.f90
!
! written by Zeng Zhuo-Quan
!
! date: 2009 - 12 - 08
Module ReadIrregularDataFile
contains
subroutine ReadString(str, IA, ND)
implicit none
character(len = *), intent(in):: str
integer, intent(out):: IA(:)
integer, intent(out):: ND
! *** *** *** *** *** immediate variable *** *** *** *** ***
logical:: LFT
character(len = 1):: ch
integer:: iL ! for loop
character(len = len(str)):: cstr
integer:: str_len
integer:: bi(size(IA)) ! begin index
integer:: ei(size(IA)) ! end index
ND = 0
cstr = adjustL(str)
str_len = len_trim(cstr)
if ( str_len == 0 ) return
LFT = .true.
Do iL = 1, str_len, 1
ch = cstr(iL : iL)
If ( ch /= " " .and. LFT ) Then
ND = ND + 1
LFT = .false.
bi(ND) = iL
Else If ( (ch == " ") .and. (.not. LFT) ) Then
LFT = .true.
ei(ND) = iL - 1
End If !
End Do
ei(ND) = str_len
Do iL = 1, ND, 1
read(cstr(bi(iL) : ei(iL)), *) IA(iL)
End Do ! iL
IA(ND + 1 : size(IA)) = 0
return
end subroutine
subroutine DataNo(str, ND)
implicit none
character(len = *), intent(in):: str
integer, intent(out):: ND
! *** *** *** *** *** immediate variable *** *** *** *** ***
logical:: LFT
character(len = 1):: ch
integer:: iL ! for loop
character(len = len(str)):: cstr
integer:: str_len
cstr = adjustL( str )
ND = 0
str_len = len_trim(cstr)
IF ( str_len > 0 ) THEN
LFT = .true.
Do iL = 1, str_len, 1
ch = cstr(iL : iL)
If ( (ch /= " ") .and. LFT ) Then
ND = ND + 1
LFT = .false.
Else If ( (ch == " ") .and. (.not. LFT) ) Then
LFT = .true.
End If !
End Do
END IF ! str_len > 0
return
end subroutine
End Module
program main
use ReadIrregularDataFile
implicit none
integer, parameter:: NC = 100
integer, parameter:: NR = 10
integer:: IA(NR)
integer:: IB(NR, NC)
integer:: iL ! for loop
character(len = 300):: str_in
character(len = 30):: fmt_str
integer:: ND !
str_in = " 312 43 034 578 986 72786 12365 587363"
call ReadString(str_in, IA, ND)
fmt_str = "(??I7)"
write(fmt_str(2 : 3), "(I2)") NR
write(*, fmt_str) IA
open(unit = 5, file = "In05.dat")
Do iL = 1, NC, 1
read(unit = 5, fmt = "(A300)", end = 100) str_in
call ReadString(str_in, IB(:, iL), ND)
End Do ! iL
100 close(5)
ND = iL - 1
open(unit = 6, file = "Out06.dat")
Do iL = 1, ND, 1
write(6, fmt_str) IB(1 : 10, iL)
End Do ! iL
close(6)
open(unit = 5, file = "In05.dat")
Do iL = 1, NC, 1
read(unit = 5, fmt = "(A300)", end = 200) str_in
call DataNo(str_in, ND)
read(str_in, *) IB(1 : ND, iL)
End Do ! iL
200 close(5)
ND = iL - 1
open(unit = 7, file = "Out07.dat")
Do iL = 1, ND, 1
write(7, fmt_str) IB(1 : 10, iL)
End Do ! iL
close(7)
stop
end program main
! In05.dat
51201 1981 1 2 1 1931 2031
51202 1982 1 1 0
51203 1983 1 2 1 1930 2030
51204 1984 1 2 1 1932 2032
51205 1985 1 2 1 1935 2035
51216 1986 1 3 0
51217 1987 1 3 0
51218 1988 12 31 1 1430 1620
52999 1989 1 1 1 1050 1100
53000 1990 1 2
312 43 034 578 986 72786 12365 587363
13312 43 034 1578 9861 727863 123657 587363 993
123 457
8 楼
shenjinggege [专家分:3260] 发布于 2009-12-08 01:46:00
1 Institute of High Energy Physics, CAS, P.O. Box 918–4, Beijing 100049, China
2 College of Physical Sciences, Graduate University of Chinese Academy of Sciences, Beijing 100049, China
呵呵
9 楼
wusicheng [专家分:10] 发布于 2009-12-24 10:20:00
学习
10 楼
wusicheng [专家分:10] 发布于 2009-12-24 10:24:00
read(100,'(A)',advance='no',eor=168) str_one_record
168 read(str_one_record,*,end=999) int_array(count,1:i)
这两句advance 和 end 是什么作用,看不大明白,请教!
我来回复