【问题标题】:Fortran read statement's iostat parameter returning code 5001Fortran 读取语句的 iostat 参数返回码 5001
【发布时间】:2020-12-12 15:36:25
【问题描述】:

我正在编写一个计算 BMI 的 fortran 小代码,但我对 read 语句的 iostat 参数有一个问题。整个代码如下:

program calculate_bmi
  ! Simple BMI calculator
  implicit none
  character :: unit_system
  character :: height_unit*15, weight_unit*10
  real :: height, weight, bmi
  integer :: ierror


  print *, 'Would you like to use imperial or metric system?'
  systemloop: do
    print *, 'Press [I] for imperal system or press [M] for metric system.'
    read *, unit_system
    if (unit_system == 'i' .or. unit_system == 'I' .or. &
     unit_system == 'm' .or. unit_system == 'M') exit systemloop
  end do systemloop

  if (unit_system == 'i' .or. unit_system == 'I') then
    height_unit='inches'
    weight_unit = 'pounds'
  else
    height_unit = 'centimeters'
    weight_unit= 'kilograms'
  end if

  print *, 'Type in your height in ', height_unit
  read (*, iostat = ierror) height
  if (ierror /= 0) then
    print *, 'Invalid input for height!'
    call exit
  end if
  print *, 'Type in your weight in ', weight_unit
  read (*, iostat = ierror) weight
  if (ierror /= 0) then
    print *, 'Invalid input for weight!'
    call exit
  end if

  if (unit_system == 'i' .or. unit_system == 'I') then
    bmi = 703 * weight / (height**2)
  else
    bmi = weight / ((height/100)**2)
  end if

  print *, 'Your BMI is: '
  write (*, 1) NINT(bmi*10)/10.0
  1 format(f6.1)
end program calculate_bmi

问题出现在这段代码:

 print *, 'Type in your height in ', height_unit
  read (*, iostat = ierror) height
  if (ierror /= 0) then
    print *, 'Invalid input for height!'
    call exit
  end if
  print *, 'Type in your weight in ', weight_unit
  read (*, iostat = ierror) weight
  if (ierror /= 0) then
    print *, 'Invalid input for weight!'
    call exit
  end if

iostat 总是将 5001 作为代码返回,并且 read 语句不会等待输入而只是终止程序。我做了一些谷歌搜索,但无法真正弄清楚到底是什么问题。如果我从 read 语句中删除 iostat,代码可以正常工作,但在这种情况下,我没有任何错误处理和防止错误输入的方式。

我对 fortran 有点陌生,所以请让我知道我在哪里犯了错误。我也使用 Gfortran 作为我的编译器。

【问题讨论】:

    标签: io fortran gfortran


    【解决方案1】:

    read 语句通常需要两个位置参数,一个用于输入单元(或* 将其声明为标准输入),另一个用于格式(或同样,* 用于计算本身)。

    不带括号,即带

    read *, some_var
    

    该命令自动默认为标准输入流,因此单个* 仅用于格式。但是一旦使用了括号,就需要同时声明输入单位和格式。

    read 语句,以及 openclosewrite,现在支持 iomsg 参数,这是一个字符串,并为错误。

    尝试像这样修改它:

    character(len=100) :: ioerrmsg
    ...
    read (*, *, iostat=ioerror, iomsg=ioerrmsg) weight
    if (ioerror /= 0) then
        print *, "Encountered Error:"
        print *, ioerrmsg
        call exit
    end if
    

    这应该会给你一些关于正在发生的事情的提示。

    干杯

    PS:如果有人知道iomsg 字符串默认有多长,请在 cmets 中告诉我。但是长度 100 通常对我有用。

    【讨论】:

    • 我觉得很愚蠢,这是我错过的一个参数。非常感谢您的回答和解释,它解决了问题!
    • 消息字符串有多长并不重要。重要的是接收它的变量的长度。 iomsg=str 将填充或截断刺以适应 str
    • @evets 是的,但我想知道iomsg 参数的最短长度,这样它就不会被截断。不急,但我想知道。
    • @chw21,我认为没有可移植的答案,因为 Fortran 标准确实规定了 iomsg 值的长度。 OTOH,似乎编译器编写者往往对错误消息很简洁。出于实际目的,我怀疑您可以使用长度为 128 的字符串。
    猜你喜欢
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    • 2013-05-02
    • 2019-07-21
    • 1970-01-01
    • 2015-11-22
    • 1970-01-01
    相关资源
    最近更新 更多