Fortran 读取语句的 iostat 参数返回代码 5001

Fortran read statement's iostat parameter returning code 5001

我正在用 Fortran 编写一段计算 BMI 的小代码,但我对读取语句的 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 总是returns 5001 作为代码,read 语句不等待输入,只是终止程序。我做了一些 Google-ing 但无法真正弄清楚到底是什么问题。如果我从读取语句中删除 iostat,代码工作正常,但在那种情况下,我无法处理错误和防止错误输入。

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

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字符串默认有多长,请在评论中告诉我。但是长度 100 通常适合我。