Arrays 如何从ASCII STL文件中读取字符数组形式的数据并将其转换为实数?

Arrays 如何从ASCII STL文件中读取字符数组形式的数据并将其转换为实数?,arrays,stl,fortran,character,ascii,Arrays,Stl,Fortran,Character,Ascii,我正在写一个Fortran程序,它从一个ASCII STL文件中读取信息并将其写入另一个文件 该文件的结构如下: solid model facet normal n1 n2 n3 outer loop vertex v1x v1y v1z vertex v2x v2y v2z vertex v3x v3y v3z endloop endfacet facet norm

我正在写一个Fortran程序,它从一个ASCII STL文件中读取信息并将其写入另一个文件

该文件的结构如下:

solid model
    facet normal n1 n2 n3
        outer loop
            vertex v1x v1y v1z
            vertex v2x v2y v2z
            vertex v3x v3y v3z
        endloop
    endfacet
    facet normal n1' n2' n3'
        outer loop
            vertex v1x' v1y' v1z'
            vertex v2x' v2y' v2z'
            vertex v3x' v3y' v3z'
        endloop
    endfacet
    .
    .repeats 
    .
    endsolid
换句话说,这些文件由未知数量的三角形面组成,每个面都包含上述模式中的信息

我使用字符可分配字符数组来避免必须指定输入文件的格式,因为输入文件的格式不同,我无法控制它

这是必要的,因为我无法预先知道读取的每个文件的精确格式,因为它们并不总是相同的

此外,在这种文件格式中,我无法预先知道每个文件包含的方面的数量

到目前为止,我用来读取文件的策略是将字符数组声明为

   character(len=:), dimension(:), allocatable :: line
以及分配和取消分配我需要的每一行的可用职位数量,因为它们各不相同

如果我理解正确,我的问题是如果不指定每个位置的长度,就无法分配数组“行”的位置。但事实上,我不知道我需要提前分配每个职位的时间长度。例如,在此文件中,我有以下方面:

facet normal 0.000000e+00 -1.000000e+00 0.000000e+00
   outer loop
      vertex 0.000000e+00 0.000000e+00 0.000000e+00
      vertex 1.500000e+02 0.000000e+00 0.000000e+00
      vertex 0.000000e+00 0.000000e+00 5.000000e+01
   endloop
endfacet
而在另一个文件中,我有(注意,在这个文件中,“外部循环”写在“facet normal”之后仅1个空格的下一行中;在第一个文件中,有3个空格):

*)如何使用字符数组读取任何文件格式?有可能吗

2) 例如,如果我尝试

  allocate(character(len=*) :: line(5))
我得到一个错误:

 allocate(character(len=*) :: line(5))

 internal compiler error: in gfc_trans_allocate, at fortran/trans-stmt.c:5697

 1face.f90:27:0: internal compiler error: Abort trap: 6
 gfortran: internal compiler error: Abort trap: 6 (program f951)
 Please submit a full bug report,
 with preprocessed source if appropriate.
 See <http://gcc.gnu.org/bugs.html> for instructions.
我明白了

 allocate(character(len=:) :: line(5))
         1
 Error: Type-spec at (1) cannot contain a deferred type parameter 
4) 我试过用真实的格式来阅读,但不起作用。 如果我尝试使用一个真正的可分配变量并分配它

 real, dimension(:), allocatable :: line
 allocate(line(5))
我的编译器没有抱怨,但是这个变量从文件中读取垃圾:对于上面的相同示例,我得到

4.15787011E+21   1.24145785E+28   2.73757760E+20   4.00465633E-11   4.00463551E-11
5) 最后,我尝试以字符数组的形式读取信息

read(unit=iunit, iostat=ios) line
这很好,但在读取之后,我需要用数据进行计算。所以我想我可以把它转换成一个真正的一维数组,对吗

我尝试使用字符可分配数组读取该行

read(iunit, iostat=ios) line
并使用

但是我得到了

Fortran runtime error: End of record
考虑到这一点,有人能帮我吗?我该怎么办?我应该:

  • 坚持字符读取,并尝试用另一种方式将数据转换为实数

  • 试试别的吗


很久以前我会用

implicit none
integer ii
character*255 line
read(10,*) line
do ii =1,255
  if (line(ii:ii) .ne. " " ) then
   istart = ii
 endif
等等。将字符串的部分转换为适当的类型。 例如,iarray=int(char(istart:istop))

这不是官方代码块。这是为了传达逻辑。用户需要定义read语句中使用的单元10,并为解析器声明其他变量

这是一个字符解析器,您可以检查数组中的每个字符,并将其转换为实数、整数或其他形式。在任何文件上都可以正常工作


现在可能有更快的方法来实现这一点,但我的方法应该可以很好地工作。

对所有Fortran问题都使用tag。您的代码并不使用非常旧的Fortran 90。Fortran 90中没有可分配的字符串。我为回答您前面的问题而发布的代码回答了这个问题。我会让其他人投票关闭这个复制品,以防我遗漏了这个版本的一些微妙之处。嘿,马克!我看过你的帖子,但由于我的无知,我一直没能实现你的建议。我的编译器到处抱怨“意外的数据声明语句”。您描述的类型应该在主程序中声明吗?还是在函数内部?马塞洛:从我的角度来看,从去年八月开始,你已经问了四次基本相同的问题了。每一个版本都是在整理一段代码以读取STL文件方面的又一次暗中尝试。你似乎没有学到任何东西,我看不到任何证据表明你已经认真地解决了自己的问题,无论是通过让我在回答你的原始问题时提供的代码发挥作用,还是通过任何其他方式。所以,我在这里是为了帮助你们,而不是为你们做工作。我现在看到,在你们对前面那个问题的评论中,你们写道,我已经设法修复了我的程序,现在我能够正确地读取任何STL文件,所以你们为什么还要问这个问题?这只是一个逻辑的例子。唯一的错误是if语句后面的三个点,它只是用来指示后面的行,我故意把括号从if语句中去掉,以表明它不是真正的代码。我没有试图为OP编写代码。但如果OP认为它是合法代码,我会更正它。在字符和字符串中仍然存在错误,需要:当索引时,但不管怎样。抱歉,但我没有看到错误?请你把它们指出来让我知道好吗。如果你有时间。如果这是为了展示如何使用Fortran从字符串中去掉前导空格,也许你会对内在函数
adjustl
感兴趣。不,我创建了一个字符解析器。您可以搜索字符sting或空格,并将行中的数字转换为数字。搜索线(开始:istart+6)=“顶点”
write(line,*) real_line
Fortran runtime error: End of record
implicit none
integer ii
character*255 line
read(10,*) line
do ii =1,255
  if (line(ii:ii) .ne. " " ) then
   istart = ii
 endif