在 FORTRAN 中读取输入文件
目的:创建一个程序,获取两个单独的文件,打开并读取它们,将它们的内容分配给数组,对这些数组进行一些数学运算,创建一个包含产品编号的新数组,打印到新文件。够简单吧?
我的输入文件开头有注释字符。一个麻烦是,它们是“#”,这是大多数绘图程序的注释字符,但 FORTRAN 不是。告诉计算机不要看这些字符的简单方法是什么?由于我以前没有 FORTRAN 经验,因此我正在使用两个测试文件来研究这个问题。这是我到目前为止所得到的:
PROGRAM gain
IMPLICIT NONE
REAL, DIMENSION (1:4, 1:8) :: X, Y, Z
OPEN(1, FILE='test.out', &
STATUS='OLD', ACTION='READ') ! opens the first file
READ(1,*), X
OPEN(2, FILE='test2.out', &
STATUS='OLD', ACTION='READ') ! opens the second file
READ(2,*), Y
PRINT*, X, Y
Z = X*Y
! PRINT*, Z
OPEN(3, FILE='test3.out', STATUS='NEW', ACTION='WRITE') !creates a new file
WRITE(3,*), Z
CLOSE(1)
CLOSE(2)
CLOSE(3)
END PROGRAM
PS。请不要用一堆代码让我不知所措。我是一个完全的编程新手。我不明白所有的行话,这就是为什么我来到这里而不是在现有网站中寻找帮助。谢谢。
Purpose: Create a program that takes two separate files, opens and reads them, assigns their contents to arrays, do some math with those arrays, create a new array with product numbers, print to a new file. Simple enough right?
My input files have comment characters at the beginning. One trouble is, they are '#' which are comment characters for most plotting programs, but not FORTRAN. What is a simple way to tell the computer not to look at these characters? Since I have no previous FORTRAN experience, I am plowing through this with two test files. Here is what I have so far:
PROGRAM gain
IMPLICIT NONE
REAL, DIMENSION (1:4, 1:8) :: X, Y, Z
OPEN(1, FILE='test.out', &
STATUS='OLD', ACTION='READ') ! opens the first file
READ(1,*), X
OPEN(2, FILE='test2.out', &
STATUS='OLD', ACTION='READ') ! opens the second file
READ(2,*), Y
PRINT*, X, Y
Z = X*Y
! PRINT*, Z
OPEN(3, FILE='test3.out', STATUS='NEW', ACTION='WRITE') !creates a new file
WRITE(3,*), Z
CLOSE(1)
CLOSE(2)
CLOSE(3)
END PROGRAM
PS. Please do not overwhelm me with a bunch of code monkey gobblety gook. I am a total programming novice. I do not understand all the lingo, that is why I came here instead of searching for help in existing websites. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您的意思是注释仅位于文件的开头,则相当简单 - 无需计算注释行数或倒带文件 - 您可以将这些行读入字符串并测试它们是否是注释。然后你最终会遇到非注释行。问题:它将被读入字符串,因此无法用于常规读取...解决方案...使用“退格键”取消读取一条记录,以便您现在可以使用正常的文件读取来读取文件的其余部分。如果注释行散布在整个文件中,则需要稍微复杂的解决方案 - 如前所述,将这些行读入字符串,然后从字符串中读取。
这是一个有效的例子......我假设“#”位于第一列和各种其他简化假设。一些建议:将子例程和函数放入模块中并“使用”该模块——这将允许编译器检查接口。当您开发程序时,请使用尽可能多的代码检查和警告选项 - 特别是下标边界检查 - 它最终会节省时间。
PS 从 Fortran 90 开始,它被正式称为“Fortran”——对于 FORTRAN 77 及更早版本,它被称为“FORTRAN”。
一些测试数据显示了输入数据的灵活性:
If you mean that the comments are only at the beginning of the file, it is fairly simple -- no need to count the comment lines or rewind file -- you can read the lines into a string and test whether they are a comment. Then you will eventually encounter a non-comment line. Problem: it will have been read into a string and thus not available for a regular read ... solution ... use "backspace" to unread one record so that you can now use normal file reads to read the rest of the file. A slightly more complicated solution would be necessary if comment lines were interspersed throughout the file -- as already stated, read the lines into a string, then read from the string.
Here is a worked example ... I have assumed that the "#" is in the first column and various other simplifying assumptions. Some recommendations: put your subroutines and functions into a module and "use" that module -- this will allow the compiler to check the interfaces. As you are developing your programs, use as many code checking and warning options as possible -- especially subscript bounds checking -- it will save time in the end.
P.S. It is officially "Fortran" since Fortran 90 -- it was "FORTRAN" for FORTRAN 77 and earlier.
And some test data to show how flexible the input data can be:
编写一个子例程,将该逻辑放入一个位置,以便您可以为两个文件调用它。您需要将每一行作为字符串读取,并添加 IF 测试来检查给定行是否以“#”开头。如果该行以“#”开头,则只需阅读下一行。如果不是,请将字符串转换为值并将其添加到您要返回的值数组中。
Write a subroutine that puts this logic into one spot for you so you can call it for both files. You'll need to read each line as a string and add an IF test to check whether a given line starts with a "#" or not. If the line starts with a "#", just read the next line. If not, convert the string to a value and add it to the array of values you're returning.
我对 FORTRAN 77 之外的任何内容都不太熟悉,但这里有一些提示(以及您在答案中发布的内容的工作版本)。首先是工作代码(我添加了行号):
差异是:
您可以将 myfile 例程定义为子例程,而不是使用函数。在这种情况下,您肯定需要传入要填充的数组作为参数。您不需要第 10 行,并且无需将返回值分配给主程序中的变量,而是“调用”例程。即第 14 行看起来像这样:
编辑:
我发布了此内容,然后意识到我忘记回答最初的问题。我这样做了,然后由于某种原因无法连接到 SO 来上传编辑。所以他们终于来了。
这样就可以进行例行编译了。要实际处理注释行,您有多种选择(至少这些是最初想到的)。这些按从最简单/最脆弱到更健壮/一般的顺序排列:
您选择哪种方法(其他人可能有其他建议)取决于您的特定应用程序。祝你好运。
I'm not real familiar with anything beyond FORTRAN 77 but here are a few pointers (and a working version of what you posted in your answer). First the working code (I added line numbers):
The differences are:
Instead of using a function, you could define this your myfile routine as a subroutine instead. In this case you would definitely need to pass in the array you want filled as a parameter. You wouldn't need line 10 and instead of assigning the return value to a variable in the main program you would 'call' the routine. i.e. line 14 would look like this:
EDIT:
I posted this and then realized I forgot to answer the original questions. I did so and then for some reason couldn't connect to SO to upload the edits. So here they are finally.
That gets your routine compiling. To actually deal with the comment lines, you have several options (at least these are the ones that come to mind initially). These are in order from simplest/most brittle to more robust/general:
Which method you choose (and other people may have other suggestions) depends on your particular application. Good luck.