文件描述:STL 文件由
solid <solid_name>
facet normal n1 n2 n3 (the triangles normal vector)
outerloop (one of the markers I want to read)
v1 x1 y1 z1
v2 x2 y2 z2 (three vertex of the triangle/facet)
v3 x3 y3 z3
endloop
end facet
endsolid
这个想法是阅读每行中的信息。首先,我正在尝试阅读第一行:固体
program Leitura
!use, intrinsic :: trim
implicit none
integer ilo, ierror, ihi, ios, iunit, num_text, len_blanck,
len_word,
len_text, i
character(len=80) :: filename
character(len=:), dimension(:), allocatable :: text, lenc
character(len=:), dimension(:), allocatable :: word
character(len=:), dimension(:), allocatable :: blanck
len_blanck=1
len_word=11
len_text=256
allocate(character(len=len_blanck) :: blanck(1))
allocate(character(len=len_word) :: word(1))
allocate(character(len=len_text) :: text(1))
allocate(character(len=len_text) :: lenc(1))
blanck= " "
ierror = 0
iunit=10
filename="Esfera.stl"
!Opening the STL file
open(unit=iunit, file=filename, status='old', access='stream', form='unformatted')
! If NUM_TEXT is zero, then initialize TEXT.
!
if ( num_text <= 0 ) then
num_text = 0
text = blanck
end if
!
! If TEXT is blank, try to read a new line from the file.
if ( ios /= 0 ) then
ierror = 1
word = blanck
text = blanck
return
end if
num_text = num_text + 1
!Reading the first line of information- should be solid name, aka, ! !the name of the solid
read ( iunit, '(a)', iostat = ios ) text
do i=1,len(text)
if ( text(i)==blanck ) then
word = blanck
return
end if
end do
!
! Extract the next word from TEXT into WORD and return.
!
lenc = len_trim ( text )
!
! Find ILO, the index of the first nonblank in TEXT.
!
ilo = 1
do while ( text(ilo:ilo) == blanck )
ilo = ilo + 1
end do
!
! Find IHI, the index of the last consecutive nonblank after the one
! at ILO.
!
ihi = ilo
do while ( ihi+1 <= lenc )
if ( text(ihi+1:ihi+1) == blanck ) then
exit
end if
ihi = ihi + 1
end do
!
! Set WORD.
!
word = text(ilo:ihi)
!
! Slide TEXT to the left.
!
if ( ihi+1 <= lenc ) then
text = text(ihi+1:)
else
text = ' '
end if
return
end program Leitura
我没有时间写一个完整的答案,但以下内容 片段应该让你开始工作代码。
首先,我认为你试图走错了方向 在读取 STL 文件时对其进行解析。 STL文件格式是相当的 干净,在实践中,一个示例和 下一个。 这不像某些具有一千种不同类型的文件格式 的线路,不知道接下来会发生什么。 我们将从假设开始 输入文件结构良好。 我们将从代码开始 这几乎没有错误处理,因为:
- 几乎不需要;
- 包括它将有助于埋葬这个答案的重要部分 进入许多如果和其他;和
- 除非您打算编写代码来修复损坏的 STL 文件, 唯一需要的错误处理是报告无法读取 文件中的实心。
当然,我们将从一些数据结构开始, 特别是一个用于实体,一个用于刻面。 喜欢 这:
TYPE facet
REAL, DIMENSION(3) :: normal
REAL, DIMENSION(3,3) :: vertices
END TYPE facet
TYPE solid
CHARACTER(len=64) :: label
TYPE(facet), DIMENSION(:), ALLOCATABLE :: facets
END TYPE solid
TYPE(solid) :: model
我将代码包装以将文件读取到一个函数中,并像 这:
model = read_solid('filename.stl')
现在,对于它的实质,函数定义
FUNCTION read_solid(fn) RESULT(mdl)
! Read solid from file fn
CHARACTER(*), INTENT(in) :: fn
TYPE(solid) :: mdl
! Local variables
INTEGER :: nu
INTEGER :: ix, jx, num_facets
CHARACTER(len=132) :: line
CHARACTER(len=8) :: word1, word2
! Executables
num_facets = 0
OPEN(newunit=nu, file=fn, status='old')
读取文件,计算分面的数量,为它们分配空间,然后倒带
ios = 0
! Now find out how many facets there are in the file
DO WHILE (ios==0)
READ(nu,'(a132)',iostat=ios) line
! Count the facets in the file
line = ADJUSTL(line)
IF (line(1:5)=='facet') num_facets = num_facets+1
END DO
ALLOCATE(mdl%facets(num_facets))
REWIND(nu)
从头开始再次读取文件,在此传递上获取固体:
ios = 0
! Ignore any leading blank lines
sol: DO WHILE (ios==0)
READ(nu,'(a132)',iostat=ios) line
! If the line is empty, get the next one
IF (LEN_TRIM(line)==0) CYCLE sol
使用adjustl
修剪线条中的任何前导空格
line = ADJUSTL(line)
IF (line(1:5)=='solid') THEN
! We've already read the line from the file, now use an
internal read
READ(line,*) word1, mdl%label
EXIT sol
ELSE ! The line didn't start with 'solid'
! Do something
END IF
END DO sol
变量word1
和word2
用于"捕获"我们不是的字符串 真正感兴趣的是,他们的内容被忽略了。 下一个块读取分面。
fct: DO ix = 1, num_facets
DO WHILE (ios==0)
READ(nu,'(a132)',iostat=ios) line
IF (LEN_TRIM(line)==0) CYCLE fct ! ignore any blank lines
line = ADJUSTL(line)
IF (line(1:5)=='facet') THEN
READ(line,*) word1, word2, mdl%facets(ix)%normal
READ(nu,*) aline ! this should be 'outer loop' and we ignore it
DO jx = 1, 3
READ(nu,*) word1, mdl%facets(ix)%vertices(jx,:)
END DO
ELSE ! The line didn't start with 'facet'
! Do something
END IF
END DO
END DO fct
CLOSE(nu)
! If anything has gone wrong reading the file, return an empty solid.
IF (ios/=0) DEALLOCATE(mdl%facets)
END FUNCTION read_solid
我的方法和 OP 之间的主要区别在于,我依靠列表导向的输入来处理查找行中的字段,并正确读取字符串、实数等。 如果 STL 文件是干净的,这是一个明智的方法,如果您正在使用脏的 STL 文件,请在源头修复它们。
最后,这实际上并没有回答OP关于如何逐个字符读取字符串并解释它们的问题。 它也不会修复发布的代码 OP 中的任何错误清单。