【问题标题】:How to read a matrix and write certain values to a new file in Fortran如何读取矩阵并将某些值写入 Fortran 中的新文件
【发布时间】:2012-10-13 14:28:57
【问题描述】:

我正在做一个化学研究项目,目前在一个名为 Connectivity-M.txt 的文件中有一个 378 x 378 的零和一矩阵。我正在尝试编写一个简单的程序来读取矩阵的每一列并查找值为 1 的条目。由于矩阵的格式为A(i,j),我想编写程序以将它找到的每个值的ij 位置写入一个新文件Wires.txt。到目前为止,这是我的代码:

program connectivity_matrixread

IMPLICIT none
integer :: i , j
INTEGER, DIMENSION(378,378) :: A

open(unit = 1 , file = "Connectivity-M.txt")
open(unit = 2 , file = "Wires.txt")

! Read values
do i = 1 , 378
    do j = 1 , 378


        Read(1,*) A(i,j)

        if (A(i,j) .eq. 1) then
            write(2,*) i , j
        endif

    enddo
enddo

end program connectivity_matrixread

程序设法读取第一列,其中只有一个值为 1 的条目。它写入此条目的 i,j 位置,否则我收到一条错误消息:

在文件 conn-read.f90 的第 25 行(单位 = 1,文件 = 'Connectivity-M.txt')
Fortran 运行时错误:文件结束

移动打开文件语句后,我仍然遇到同样的错误。错误所指的行包含读取语句。

【问题讨论】:

  • 花几分钟时间来熟悉一下 SO 以及如何最好地在这里提出问题。特别是,弄清楚如何将您的代码格式化为代码 sn-ps;查看文本编辑框上方的小图标,尤其是看起来像{} 的那个。我和许多 Fortran 程序员一样,年纪太大,脾气暴躁,无法帮助那些没有尽可能简单的人。

标签: fortran fortran90


【解决方案1】:

根据输入文件内容的布局和打开方式,您可能可以在一行中读取它,如下所示:

read(1,*) A

让 Fortran 处理细节。如果您的数组以行优先顺序存储,我希望这种快速简便的方法会以“错误”的顺序读取它,因此您可能希望在读取后转置数组。或者你可能想像这样逐行阅读它:

do ix = 1,nrows
    read(1,*) A(ix,:)
end do

这些方法只有在文件的每一行中有正确数量的整数和正确的行数时才有效。

我在写的时候,有一些不经意的建议:

  • 不要养成在程序中使用单位数字标识符的习惯。如今,在您的程序启动时发现除了 0、5 和 6 以外的标识符已经在使用中是很不寻常的,但并非完全不可能。如果您有(非常)最新的编译器,请在您的 OPEN 语句中使用选项 NEWUNIT=UNIT,如果没有,请使用至少 2 位数字。
  • 现在是 21 世纪,你可以放弃陈旧的.eq.,现在使用==;看起来 Fortran 95 及更高版本已获得认可。

回答您的问题:是的,错误语句是指发生错误时正在执行的源代码行。文件意外结束的最可能原因是文件不在程序正在查找的位置(Fortran 认为不存在的文件与空文件几乎相同)或文件包含的数据较少比你试图从中读取。后一个错误的原因可能是文件包含的数据比您想象的要少,或者您的读取语句尝试读取的数据比您想象的要多。如果没有看到您的输入文件,我无法判断是哪种情况。无论您做什么,都不要发布您的整个输入文件,但如果您仍然遇到问题,请发布它的 sn-p。

要在尝试打开文件之前检查文件是否存在,请使用inquire 语句。

我怀疑你还没有完全弄清楚发生了什么,因为你编写了程序设法读取第一列,而你的代码很清楚地将值读入逐行排列。

【讨论】:

    【解决方案2】:

    在此之后可能需要进行更多调整,但第一步是将 open 语句向上移动到循环上方,如下所示:

    open(unit = 1 , file = "Connectivity-M.txt")
    
    do i = 1 , 378
    
        do j = 1 , 378
    

    原因是该文件应该只打开一次,然后你遍历它。

    发布您的结果,我们会看看接下来会发生什么。

    【讨论】:

    • 重要提示:请注意High Performance Mark的评论。了解 Stack Overflow 如何工作是一个好主意,以使通信顺畅。实际上,您可以在那里编辑您的问题并更新您的代码。选择代码部分并点击 {} 按钮。哦,我明白了;伟大的!看看@Chris 做了什么。
    • 我不确定我是否正确发布,但我更新了上面的代码。所涉及的任何逻辑似乎有缺陷吗?
    • 现在,最有可能的是输入文件。我相信 Read(1,*) A(i,j) 期望每行一个数字。最有可能的是,事实并非如此。每行实际上包含什么?
    猜你喜欢
    • 1970-01-01
    • 2019-03-11
    • 1970-01-01
    • 2013-09-21
    • 2019-06-12
    • 2020-10-01
    • 1970-01-01
    • 2015-01-26
    • 1970-01-01
    相关资源
    最近更新 更多