Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在旧版Fortran中读取包含字符的文本文件_Fortran_Character_Fortran77 - Fatal编程技术网

在旧版Fortran中读取包含字符的文本文件

在旧版Fortran中读取包含字符的文本文件,fortran,character,fortran77,Fortran,Character,Fortran77,在将遗留Fortran代码包装到R中的项目中,文本文件由子程序“rfort”读取。子例程的工作简化版本如下所示: SUBROUTINE rfort() implicit none INTEGER I,IX,IY DIMENSION IX(10),IY(10) CHARACTER*6 NAME(10) OPEN(UNIT=8,FILE='TEST.DAT',STATUS='OLD') OPEN(UNIT=9,FILE='RESULT.DAT',STATUS='UNK

在将遗留Fortran代码包装到R中的项目中,文本文件由子程序“rfort”读取。子例程的工作简化版本如下所示:

  SUBROUTINE rfort()
  implicit none

  INTEGER I,IX,IY
  DIMENSION IX(10),IY(10)
  CHARACTER*6 NAME(10)

  OPEN(UNIT=8,FILE='TEST.DAT',STATUS='OLD')
  OPEN(UNIT=9,FILE='RESULT.DAT',STATUS='UNKNOWN')

  DO I=1,10
  READ(8,1020)IX(I),IY(I),NAME(I)
1020      FORMAT(8X,2I8,A6)
  WRITE(9,1030)IX(I),IY(I),NAME(I)      
1030      FORMAT(8X,2I8,A6)
  ENDDO
  CLOSE (8)
  CLOSE (9)
  END
文本文件(“TEST.DAT”)由四个变量组成:一个行标识符(忽略)、两个整数变量(“IX”、“IY”)和一个字符变量(“NAME”)

而子例程(在MacOS 10.11.6、R 3.5.0上)可以使用

也可以在R中使用

dyn.load("rfort.so")
运行时不会出错

.Fortran("rfort")

奇怪的是,它只读取“RESULT.DAT”测试的整数列。不管我怎么做,字符列都被忽略了。同样的代码作为一个独立的Fortran程序(使用gfortran 6.1.0编译)也能正常工作,因此我怀疑它与格式有关。然而,我已经束手无策,所以任何帮助都是非常感谢的

我认为读取格式中的8X应该是4X。让我们看一下第一个输入行(我添加了列号):

格式为
8X、2I8、A6
。我们跳过第1-8列,从第9-16列开始读取第一个整数,即
b395bbbbb
,从第17-24列开始读取第二个整数
1232bb10
。如您所见,部分字符数据被读取为第二个整数。默认值BLANK='NULL'表示忽略嵌入的空格(我假设您没有使用FORTRAN 66编译器!)


我不知道你为什么说它似乎和格弗特兰一起工作。我也不知道为什么根据调用子例程的方式,结果会有所不同。

在您的示例中,您似乎希望输出文件由TEST.DAT的最后3列组成,但输出不是您期望看到的。 您有两种选择:1)更改TEST.DAT中的间距以匹配format语句,或2)更改format语句以匹配TEST.DAT中的间距

让我们看看您的格式语句。1020格式要求跳过前8列,从接下来的16列中读取2个整数类型(每个int对应8列),然后从接下来的6列中读取一个字符类型。例如,TEST.DAT中的第10行如下所示:

TEST.DAT (line 10) with spacing illustrated:
       |       |       |     |
123456781234567812345678123456
  10     726    1293 1078d
如您所见,值“726”读入IX(10),但“12393107”读入IY(10),而“8d”读入名称(10)。太棒了,没错,但不是你所期望的!然后在打印输出时,数字默认为右对齐,而字符默认为左对齐,因此RESULTS.DAT中的最后两列在打印时没有空格:

RESULTS.DAT (line 10) with spacing illustrated:
       |       |       |     |
123456781234567812345678123456
             726 12931078d    
我的建议是:改变你的阅读格式,让它更加宽容和灵活。只需将
1020
说明符替换为
*
,这意味着行中的每个项目(逗号或空格分隔)形成一个序列,该序列将传输到I/O列表中的相应变量中。这称为
列表定向的
格式说明符。请注意,由于行号成为输入列表的一部分,因此需要定义一个整数
integer dummy_val
(位于子例程顶部),然后可以忽略该整数。现在使用以下方法阅读每一行:

read(8, *) dummy_val, IX(i), IY(i), NAME(i)
您可以对写入语句执行相同的操作:
write(9,*)、IX(i)、IY(i)、NAME(i)
,这将使用合理的默认字段宽度,并保证i/O列表中的每个项之间存在空格。如果希望对输出的格式化方式有更多的控制,请继续使用format语句,但要对其进行更改,以确保在每个项之间放置一定数量的空格:

write(9, "(4x,I8,I8,1x,A6)") IX(i), IY(i), NAME(i)

我觉得
8X
很可能是正确的:输入文本数据的前四列被markdown解析器吞没。特别是代码和标签的缩进。谢谢您的输入,很抱歉造成混淆!我还认为
8X
是正确的。“1”由七个空格开头,“10”由六个空格开头,以此类推。第一个空格确实被吞没了。实际上我同意史蒂夫的观点,读写都是8x应该是4x。然后输入和输出的间隔相同,只是输出没有行号。但是如果你在阅读中使用
*
,就像在我的答案中一样,那么这并不重要。谢谢你的详细答案!然而,降价使间隔变大了。我编辑了“TEST.DAT”,以便它反映原始版本(行计数器有8个空格)。尽管如此,你的建议,使格式更宽容不起作用,至少在我的系统。R崩溃了,只写了“RESULT.DAT”中的第一行。@Nils崩溃可能与R有关?与gfortran和ifort在这里运行良好。write语句是否仍放在do循环中?如果不起作用,请尝试显式格式。我现在使用读取格式字符串尝试显式格式,如
1020格式(8X,I8,I8,1X,A6)
。似乎只读取字符串的第一个字符,因此使用
1X
时,名称列会出现,但只显示第一个字符(在本例中为“1”)。使用
2X
将显示第二个字符,依此类推。这肯定是一个特定于R的问题,但我仍然不知道如何解决它。
RESULTS.DAT (line 10) with spacing illustrated:
       |       |       |     |
123456781234567812345678123456
             726 12931078d    
read(8, *) dummy_val, IX(i), IY(i), NAME(i)
write(9, "(4x,I8,I8,1x,A6)") IX(i), IY(i), NAME(i)