我在文件中有2维表,如下所示:
11, 12, 13, 14, 15
21, 22, 23, 24, 25
我希望它以二维数组导入。我写了这段代码:
INTEGER :: SMALL(10)
DO I = 1, 3
READ(UNIT=10, FMT='(5I4)') SMALL
WRITE(UNIT=*, FMT='(6X,5I4)') SMALL
ENDDO
但是它会导入一维数组中的所有内容。
编辑:
我已更新代码:
program filet integer :: reason integer, dimension(2,5) :: small open(10, file='boundary.inp', access='sequential', status='old', FORM='FORMATTED') rewind(10) DO READ(UNIT=10, FMT='(5I4)', iostat=reason) SMALL if (reason /= 0) exit WRITE(UNIT=*, FMT='(6X,5I4)') SMALL ENDDO write (*,*) small(2,1) end program
这是输出:
11 12 13 14 15 21 22 23 24 25 12
答案 0 :(得分:2)
嗯,你已经将SMALL
定义为一维数组,而Fortran只是试图提供帮助。你应该像这样定义SMALL
;
integer, dimension(2,5) :: small
执行read
语句时发生的情况是系统在SMALL
已满或遇到文件末尾之前用完了编辑描述符(您指定了5个整数)。如果我没记错,Fortran将重新使用编辑描述符,直到SMALL
已满或遇到文件结尾。但是根据Fortran标准,这种行为多年来已经发生了变化,并且各种编译器已经在这部分语言中实现了各种非标准功能,因此您可能需要检查编译器的文档或进行更多实验以确切地找出会发生什么。
我认为你的代码也有点奇怪,因为你从SMALL
读了3次。为什么?
small(1,1)
,第二个元素(在内存中)是small(2,1)
,第三个元素是small(1,2)
,依此类推。我认为你的读(和写)语句不是标准的,而是广泛实现的(这在Fortran编译器中并不罕见)。我可能错了,可能是标准的。无论哪种方式,read
语句都被解释为以列为主要顺序读取small
的元素。读取的第一个数字放在small(1,1)
中,第二个放在small(2,1)
中,第三个放在small(1,2)
中,依此类推。
您的write
声明使用相同的功能;你可能已经为自己发现了这个,如果你已经用循环中的元素写出了也打印了索引。
读取数组并控制元素放入数组的顺序Fortran方法是在read语句中包含一个 implied-do 循环,如下所示:
READ(UNIT=10, FMT='(5I4)', iostat=reason) ((SMALL(row,col), col = 1,numCol), row=1,numRow)
您也可以在write
语句中使用此方法。
您还应该仔细研究编译器文档,并确定如何为所有非标准功能启用警告。
答案 1 :(得分:1)
添加高性能马克所写的......
如果要使用逗号分隔数字,则应使用列表定向的IO而不是格式化的IO。 (有时这称为无格式IO,但非标准术语很容易与二进制IO混淆)。这更容易使用,因为您不必在列中精确排列数字,并可以用空格或逗号分隔它们。读取只是“读(10,*)变量”
但坚持使用格式化IO,这里有一些示例代码:
program demo1
implicit none
integer, dimension (2,5) :: small
integer :: irow, jcol
open ( unit=10, file='boundary.txt', access='sequential', form='formatted' )
do irow=1, ubound (small, 1)
read (10, '(5I4)') (small (irow, jcol), jcol=1, ubound (small, 2))
end do
write (*, '( / "small (1,2) =", I2, " and small (2,1)=", I2 )' ) small (1,2), small (2,1)
end program demo1
使用I4格式的读取,数据需要在列中:
12341234123412341234
11 12 13 14 15
21 22 23 24 25
数据文件不应包含第一行“1234 ...” - 这是示例中的格式5I4所需的对齐方式。
使用我的示例程序,有一个用于irow的外部do循环和一个“隐含的do循环”作为read语句的一部分。你也可以消除外部的do循环,并在read语句中使用两个隐含的do循环,正如High Performance Mark所示。在这种情况下,如果保留格式规范(5I4),它将被重用以读取第二行 - 这称为格式恢复。 (在更复杂的格式上,需要阅读规则以了解格式的哪一部分在格式恢复中被重用。)这是标准的,至少从FORTRAN 77和FORTRAN IV开始。 (当然,我的例子的声明和风格是Fortran 90)。
我使用了“ubound”,因此您既不需要携带存储数组维度的变量,也不必使用特定的数值。如果您以后决定更改数组的维度,后面的方法可能会导致问题 - 然后您必须搜索所有特定值(此处为2和5)并更改它们。
在公开声明后无需倒退。