You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fortran 90整数数组转字符数组时遇文件结束错误排查

问题分析与修复:Fortran月份整数转字符数组错误

问题背景

有一个接收任意数量月份整数的模块,需要将这些整数转换为字符类型。在转换子程序中执行write(output_chars(idx),'(I2.2)') input_ints(idx)时,循环首次迭代后出现“end-of-file”错误;省略unit=无错误,但添加unit=会触发语法错误。


核心错误原因

  1. 字符数组未分配内存
    主程序中monchar是可分配字符数组,但调用转换子程序前没有为其分配与month_int相同大小的空间。向未分配的数组元素写入时,会触发内存访问异常,表现为“end-of-file”这类错误。

  2. WRITE语句语法误用
    Fortran中向字符变量写入时,不需要指定unit=参数——字符变量本身就是输出目标。unit仅用于文件/设备单元,强行添加会直接触发语法错误。

  3. 格式符与数组长度匹配问题(可选优化)
    若使用(I2.2)格式,要求字符变量长度至少为2,主程序中monchar定义为character(len=2)是符合要求的,但如果之前用(I0)格式,1位整数会只写1个字符,剩余位置留空格,不符合月份字符的固定格式需求。


修正后的完整代码

主程序部分

program ConvMonInt2MonCh
    use months_mod, only: get_months
    implicit none

    integer, allocatable               :: month_int(:)
    character(len=2), allocatable      :: monchar(:)
    integer                            :: idx

    call get_months(month_int)

    ! 关键步骤:为字符数组分配与输入整数数组相同的空间
    allocate(monchar(size(month_int)))

    ! 调用转换子程序
    call convert_monthint_to_monthchar(month_int, monchar)

    ! 打印转换结果验证
    print *, "转换后的月份字符:"
    do idx = 1, size(monchar)
        print *, monchar(idx)
    enddo

contains
    subroutine convert_monthint_to_monthchar(input_ints, output_chars)
        implicit none
        ! 哑元定义
        integer, dimension(:), intent(in) :: input_ints
        character(len=*), dimension(:), intent(out) :: output_chars

        ! 局部循环变量
        integer :: idx

        ! 前置检查:确保输入输出数组大小匹配
        if (size(input_ints) /= size(output_chars)) then
            error stop "输入输出数组大小不匹配"
        endif

        ! 循环转换每个元素
        do idx = 1, size(input_ints)
            ! 使用I2.2格式,确保输出两位字符(不足补前导零)
            write(output_chars(idx), '(I2.2)') input_ints(idx)
        enddo
    end subroutine convert_monthint_to_monthchar
end program ConvMonInt2MonCh

模块部分(months_mod.f90)

module months_mod
    implicit none
contains

    subroutine get_months(month_array)
        implicit none
        integer, intent(OUT), allocatable :: month_array(:)
        integer, allocatable              :: temp_array(:)
        integer :: n, i, xtra_month

        ! 1. 提示输入月份数量
        print*, 'Enter the number of months to process,'
        print*, '1 for one month, 2 for two months, ...:'
        print*, ' '
        read *, n

        ! 2. 分配用户指定大小的数组
        ALLOCATE(month_array(n))

        ! 3. 提示用户输入每个月份整数
        print*, 'Enter a month to process'
        print*, "1 for Jan, or more than one month, one by one, each followed by Enter:"
        print*,' '

        do i = 1, n
            read*, month_array(i)
        enddo

        ! 分配临时数组,多一个位置存储额外月份
        allocate(temp_array(n + 1))
        
        ! 计算额外月份(12月的下一个月是1月)
        if(month_array(n) == 12) then
            xtra_month = 1
        else
            xtra_month = month_array(n)+1
        endif
        
        ! 复制原数据到临时数组
        temp_array(1:n) = month_array(1:n)
        
        ! 添加额外月份
        temp_array(n + 1) = xtra_month
        
        ! 重新分配原数组并复制数据
        deallocate(month_array)
        allocate(month_array(n+1))
        month_array = temp_array
        deallocate(temp_array)
        
    end subroutine get_months
end module months_mod

额外优化说明

  • 新增数组大小检查,避免因输入输出数组长度不匹配导致的隐性错误
  • 使用I2.2格式确保输出固定两位字符(如1转为"01",12转为"12"),符合月份字符的通用格式需求
  • 主程序添加结果打印,方便快速验证转换是否正确

内容的提问来源于stack exchange,提问作者Zilore Mumba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.10 18:03:09