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

Fortran 90读取含冒号的CSV文件报错,如何解决?

Fortran 90读取CSV时因字段含空格/冒号触发list-directed I/O语法错误的解决方法

报错信息:

forrtl: severe (59): list-directed I/O syntax error, unit 21, file /data3/khee/data/AWS/ASCII/STATION/2021/csvfile/test.csv
Image              PC                Routine            Line        Source             
a.out              000000000043B9EE  Unknown               Unknown  Unknown
a.out              0000000000412AB0  Unknown               Unknown  Unknown
a.out              00000000004036D3  Unknown               Unknown  Unknown
a.out              00000000004034DE  Unknown               Unknown  Unknown
libc-2.17.so       000000333901F84D  __libc_start_main     Unknown  Unknown
a.out              00000000004033E9  Unknown               Unknown  Unknown

原代码:

program read_data

  implicit none

  integer :: HSID, DSID
  real :: HLAT, HLON, HALT, DTEMP, DWDEG, DWSPD, DPRCP, DSPRS, DMSLP, DHMD, DSR, DSRH
  character(len=16) :: DATE

  open(21,file='/data3/khee/data/AWS/ASCII/STATION/2021/csvfile/test.csv',form='formatted',access='sequential',status='old')

10  read(21,*,end=90) DSID, DATE, DTEMP, DWDEG, DWSPD, DPRCP, DSPRS, DMSLP, DHMD, DSR, DSRH
           write(*,*) DSID, DATE, DTEMP, DWDEG, DWSPD, DPRCP, DSPRS, DMSLP, DHMD, DSR, DSRH
           
go to 10
90 continue

  write(*,*) "EOF"
  stop
  
end program read_data

输入行示例:

848,2021-01-01 00:00,-4.1,9.1,2,0,,,,0,0

问题本质

你使用的列表式I/O(read(21,*))默认将空格、逗号、制表符等都视为字段分隔符。DATE字段2021-01-01 00:00中的空格会被当成分隔符,导致程序仅将2021-01-01读入DATE变量,后续的00:00会被当作下一个字段,但该字段需要匹配实数类型的DTEMP,冒号无法被解析为实数,最终触发语法错误。冒号是表象,核心是列表式读取的分隔规则与CSV结构不匹配。


解决方案

方案一:修改OPEN语句,指定仅用逗号作为分隔符

这是改动最小的方法,只需在OPEN语句中添加delim='comma'选项,强制列表式I/O仅将逗号视为字段分隔符,空格和冒号会被保留在字符字段中:

open(21,file='/data3/khee/data/AWS/ASCII/STATION/2021/csvfile/test.csv',&
     form='formatted',access='sequential',status='old', delim='comma')

修改后,原有的read(21,*,end=90)语句可以正常工作:DATE字段会完整读取2021-01-01 00:00,后续字段也能正确匹配对应类型。

方案二:先读取整行,再用内部文件解析

如果CSV格式更复杂(比如字段包含引号或嵌套逗号),可以先将整行读取到字符变量,再通过内部文件指定格式解析,精准控制每个字段的读取规则:

program read_data
  implicit none

  integer :: DSID
  real :: DTEMP, DWDEG, DWSPD, DPRCP, DSPRS, DMSLP, DHMD, DSR, DSRH
  character(len=16) :: DATE
  character(len=256) :: line  ! 存储整行内容,长度可根据实际调整

  open(21,file='/data3/khee/data/AWS/ASCII/STATION/2021/csvfile/test.csv',&
       form='formatted',access='sequential',status='old')

10 read(21, '(A)', end=90) line  ! 读取整行到字符变量
  ! 用内部文件解析,格式字符串匹配CSV的逗号分隔结构
  read(line, '(I0, ",", A16, ",", F0.0, ",", F0.0, ",", I0, ",", F0.0, ",", &
              & F0.0, ",", F0.0, ",", F0.0, ",", I0, ",", I0)') &
              & DSID, DATE, DTEMP, DWDEG, DWSPD, DPRCP, DSPRS, DMSLP, DHMD, DSR, DSRH
  write(*,*) DSID, DATE, DTEMP, DWDEG, DWSPD, DPRCP, DSPRS, DMSLP, DHMD, DSR, DSRH
           
go to 10
90 continue

  write(*,*) "EOF"
  stop
  
end program read_data

说明:I0和F0.0表示自动匹配整数/实数的长度,","用于跳过字段间的逗号,空字段会被解析为对应类型的默认值(如实数0、整数0)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 07:45:25