FORTRAN 77 简单输入/输出

发布于 2024-12-15 07:09:02 字数 1275 浏览 2 评论 0原文

我是 FORTRAN 新手,必须编写一个 FORTRAN 77 程序来从文件重定向或标准输入读取以下格式:

[CHARACTER] [REAL] [REAL] [REAL] ... (can have any number of these)
D [INTEGER] (only one of these)
[REAL] [REAL] [REAL] ... (can have any number of these)

示例输入可以是:

T 1.0 2.0 3.0
S 1.0 2.0 4.0
Y 3.0 4.0 5.0
D 2
3.0 5.0 6.0
4.5 4.6 5.6

我的母语语言是 C++,所以我不熟悉读取语句自动转到下一行的整个想法。

到目前为止,我有以下代码:

c234567
      character*1 D
      character*1 LETTER
      real X, Y, Z
      integer lines
      real point1, point2, point3

85格式(3F10.6) 100 格式(A1、5X、F10.6、5X、F10.6、4X、F10.6) 990 格式 (A, I10)

      MAX = 6
      LETTER = 'Z'
      D = 'D'

      read *, LETTER, X, Y, Z

10 if(LETTER .ne. D) then 写 (6, 100) 字母、X、Y、Z 读取 *、字母、X、Y、Z 转到10 别的 转到20 正如

C ===================================================== 20 lines = aint(X) write (*,990) 'LINES: ', lines write (6, 85) X, Y, Z read *, Z write (6, 85) X, Y, Z end

你所看到的,我得到了输入的第一部分,但之后由于读取语句:read*, Z 进入下一行,一切都变得混乱。在上面提供的特定输入文件中,我在 D 之后得到 2,以及接下来的两个值(3.0、5.0),但我跳过 6.0

任何帮助都会很棒。谢谢。

I am new to FORTRAN, and must write a FORTRAN 77 program to read the following format from a file redirection or standard input:

[CHARACTER] [REAL] [REAL] [REAL] ... (can have any number of these)
D [INTEGER] (only one of these)
[REAL] [REAL] [REAL] ... (can have any number of these)

example input could be:

T 1.0 2.0 3.0
S 1.0 2.0 4.0
Y 3.0 4.0 5.0
D 2
3.0 5.0 6.0
4.5 4.6 5.6

My native language is C++, so I'm new to this whole idea of a read statement going to the next line automatically.

So far, I have the following code:

c234567
      character*1 D
      character*1 LETTER
      real X, Y, Z
      integer lines
      real point1, point2, point3

85 format (3F10.6) 100 format (A1, 5X, F10.6, 5X, F10.6, 4X, F10.6) 990 format (A, I10)

      MAX = 6
      LETTER = 'Z'
      D = 'D'

      read *, LETTER, X, Y, Z

10 if(LETTER .ne. D) then
write (6, 100) LETTER, X, Y, Z
read *, LETTER, X, Y, Z
goto 10
else
goto 20
endif

C =====================================================
20 lines = aint(X)
write (*,990) 'LINES: ', lines
write (6, 85) X, Y, Z
read *, Z
write (6, 85) X, Y, Z
end

As you can see, I get the first portion of the input fine, but after that it kind of all goes to mush because of the read statement: read*, Z going to the next line. In my specific input file provided above, I get the 2 after the D, and the next two values (3.0, 5.0) but I skip the 6.0

Any help would be great. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

故事灯 2024-12-22 07:09:02

如果您知道您的行永远不会超过最大长度,我建议阅读整行,然后根据您的规则解析该行。

使用最大行长度为 1024 个字符的示例:

       CHARACTER*1024 line
       CHARACTER letter
100    FORMAT (A)
       READ(*,100) line
       READ(line, *) letter
       IF (letter .eq. 'T') THEN
          ...
       END IF

也许此技术适合您。

If you know that your lines will never exceed a maximum length, I suggest to read the whole line and then to parse the line according to your rules.

An example using a maximum line length of 1024 characters:

       CHARACTER*1024 line
       CHARACTER letter
100    FORMAT (A)
       READ(*,100) line
       READ(line, *) letter
       IF (letter .eq. 'T') THEN
          ...
       END IF

Maybe this technique works for you.

狂之美人 2024-12-22 07:09:02

我什至没有看过你的代码,但我会建议这样的策略

(1) read the initial character of the line
if not "D" then 
    read reals
    store the line
    loop to (1)
else
    read one integer
    store the line
    break
endif
read lines of reals until end-of-file

我的 fortran 非常生锈,但我相信有一些结构可以帮助你解决这个问题。当然,READEND 修饰符对于最后一点很有帮助。


经过一番实验,我发现 gfortran 似乎支持旧的尾随 $ 用于非高级输入约定 advance='不'。然而,g77却没有。我无法与任何其他编译器交谈——据我所知,直到 fortran 90 引入 advance='no' 之前,这从未标准化。

演示代码可以在 gfortran 中运行,但不能在 g77 中运行,

      program temp
c234567
      character a
      integer i
      real x, y, z, w(50)

c This or with (*,'(A1 $)')
      read (*,'(A1)',advance='no') a

      if (a .eq. 'D') then
         read (*,*) i
         write (*,*) a, i
      endif

      end

如果您的编译器支持非高级输入,这应该足以使增量策略起作用。不知何故。

另一种方法是将字母加上该行的其余部分读入一个大字符缓冲区,然后沿着以下行单独解析缓冲区

      character a, buf(1024)
      read (*,'(a1, a1024)') a, buf
      if (a .eq. d) then
         read (buf,*) i
      endif

I haven't even looked at you code but I would suggest a strategy like this

(1) read the initial character of the line
if not "D" then 
    read reals
    store the line
    loop to (1)
else
    read one integer
    store the line
    break
endif
read lines of reals until end-of-file

My fortran is very rusty, but I believe that there are constructs that will help you with this. Certainly the END modifier to READ is going to be helpful with the last bit.


After a little experimenting, I find that gfortran seems to support the old trailing $ for non-advancing input convention and advance='no'. However, g77 does not. I can't speak to any other compiler--as far as I know this was never standardized until fortran 90 where advance='no' was introduced.

Demo code that works in gfortran, but not in g77

      program temp
c234567
      character a
      integer i
      real x, y, z, w(50)

c This or with (*,'(A1 $)')
      read (*,'(A1)',advance='no') a

      if (a .eq. 'D') then
         read (*,*) i
         write (*,*) a, i
      endif

      end

This should be enough to make the incremental strategy work if you compiler supports non-advancing input somehow.

The alternative is to read the letter plus the rest of the line into a large character buffer, then parse the buffer separately along the lines of

      character a, buf(1024)
      read (*,'(a1, a1024)') a, buf
      if (a .eq. d) then
         read (buf,*) i
      endif
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文