Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有ascii数据的FORTRAN代码_Fortran - Fatal编程技术网

带有ascii数据的FORTRAN代码

带有ascii数据的FORTRAN代码,fortran,Fortran,我有一个ASCII格式的数据(.txt文件),其中日期以yearmonthday(即19900601)格式列给出。我想将此列分为三列,每列中有年、月和日期。有人能告诉我如何用Fortran实现这一点吗?我的数据文件和代码如下: 数据nied 19480501-1 19480502-1 19480503 2 19480504-1 19480505 2 19480506-1 19480507-1 19480508-1 19480509-1 19480510-1 19480511-1 19480512

我有一个ASCII格式的数据(.txt文件),其中日期以yearmonthday(即19900601)格式列给出。我想将此列分为三列,每列中有年、月和日期。有人能告诉我如何用Fortran实现这一点吗?我的数据文件和代码如下:

数据nied
19480501-1
19480502-1
19480503 2
19480504-1
19480505 2
19480506-1
19480507-1
19480508-1
19480509-1
19480510-1
19480511-1
19480512 2
. . . .

代码:

program ascii_read    
!real(kind=8):: rain(np)    
real,allocatable:: rain(:)    
integer::np=15739  
!integer(kind=8)::day(np)  
integer,allocatable::day(:)  
character(len = 80)::firstline  
integer::i,j  
integer,allocatable:: year(:)  
allocate (year(np-1))  
allocate (rain(np))  
allocate (day(np))  
open(1243,file="11700.text",status="unknown")
open(12,file="11700_output.text",status="unknown")
read(1243,*)firstline  

do i=2,np  
read(1243,1111)day(i),rain(i)  
end do  
1111 Format(i6,F5.2)  
write(*,*)day    
do j = 1,np-1  
year(j)=day(j)   
end do   
write(*,fmt='(i4)')year    
1 format(I4)  
!write(*,*)year  
return    
stop   
end program    

这在一列中只显示年份,而不是月份和日期。知道如何从这个数据文件中分离月份和日期吗

你必须分析你的输入和你想要的输出之间的关系,然后实现这种关系;这就是编程的工作原理。你必须先知道一种自己解决问题的方法,然后教计算机怎么做。 对于这个问题,您可以简单地看到前4位代表年份,后两位代表月份,最后2位代表日期。要得到前4个数字,将整数除以10000,只需拒绝最后4个数字(月和日)。使用模运算得到最后四个。并从最后两个月中提取月份。 定义新的数组变量
month
date
,并将它们分配到与
day
相同的大小,同时添加一个新的整数变量tmp,并将第二个循环更改为:

    do j = 1,np-1
        year(j)=day(j)/10000
        tmp = mod(day(j), 10000)
        month(j) = tmp/100
        date(j) = mod(tmp,100)
    end do
我还建议你使用免费格式阅读。您可以使用固定的写入格式来对齐数据并使其易于可视化。 当你开始的时候就开始现代编程吧。在代码中使用普通数字不是一个好主意,所以请使用命名常量作为文件ID。确保在不再需要文件时关闭它们。当您打开文件进行读取时,请使用status='old',您希望文件在那里,或者希望程序停止并显示适当的消息。使用format时,请使用
read
write
的format参数,而不是format语句,例如,使用名称arg
fmt
,就像您在某些地方所做的那样。这使得调试变得容易。所以你的程序可以是这样的

program ascii_read
    !real(kind=8):: rain(np)
    integer, parameter :: inputId = 1243
    integer, parameter :: outputId = 12
    real,allocatable,dimension(:):: rain
    integer::np=12
    !integer(kind=8)::day(np)
    character(len = 80)::firstline
    integer::i,j, tmp
    integer,allocatable,dimension(:):: day, year, month, date

    allocate ( year(np-1), rain(np), day(np), month(np), date(np) )
    open(inputId,file="11700.text",status="old")
    open(outputId,file="11700_output.text",status="unknown")
    read(inputId,*)firstline  

    do i=2,np  
        read(inputId,*)day(i),rain(i)
    end do
    close(inputId)

    write(*,*) day
    do j = 1,np-1
        year(j)=day(j)/10000
        tmp = mod(day(j), 10000)
        month(j) = tmp/100
        date(j) = mod(tmp,100)
        ! just to see what we get.
        write(*, *) day(j), year(j), month(j), date(j)
    end do
    !write(*,fmt='(i4)')year
    !1 format(I4)
    !write(*,*)year

    return
    stop
end program

感谢IanH的评论,最新版本的fortran包含了一个新的单元选项,用于为程序员处理IO单元号。这使您无需为单元号定义命名常量。如果您不使用最新版本(某些公司不经常升级),则在中有一个可供使用。

您必须分析输入和所需输出之间的关系,然后实现该关系;这就是编程的工作原理。你必须先知道一种自己解决问题的方法,然后教计算机怎么做。 对于这个问题,您可以简单地看到前4位代表年份,后两位代表月份,最后2位代表日期。要得到前4个数字,将整数除以10000,只需拒绝最后4个数字(月和日)。使用模运算得到最后四个。并从最后两个月中提取月份。 定义新的数组变量
month
date
,并将它们分配到与
day
相同的大小,同时添加一个新的整数变量tmp,并将第二个循环更改为:

    do j = 1,np-1
        year(j)=day(j)/10000
        tmp = mod(day(j), 10000)
        month(j) = tmp/100
        date(j) = mod(tmp,100)
    end do
我还建议你使用免费格式阅读。您可以使用固定的写入格式来对齐数据并使其易于可视化。 当你开始的时候就开始现代编程吧。在代码中使用普通数字不是一个好主意,所以请使用命名常量作为文件ID。确保在不再需要文件时关闭它们。当您打开文件进行读取时,请使用status='old',您希望文件在那里,或者希望程序停止并显示适当的消息。使用format时,请使用
read
write
的format参数,而不是format语句,例如,使用名称arg
fmt
,就像您在某些地方所做的那样。这使得调试变得容易。所以你的程序可以是这样的

program ascii_read
    !real(kind=8):: rain(np)
    integer, parameter :: inputId = 1243
    integer, parameter :: outputId = 12
    real,allocatable,dimension(:):: rain
    integer::np=12
    !integer(kind=8)::day(np)
    character(len = 80)::firstline
    integer::i,j, tmp
    integer,allocatable,dimension(:):: day, year, month, date

    allocate ( year(np-1), rain(np), day(np), month(np), date(np) )
    open(inputId,file="11700.text",status="old")
    open(outputId,file="11700_output.text",status="unknown")
    read(inputId,*)firstline  

    do i=2,np  
        read(inputId,*)day(i),rain(i)
    end do
    close(inputId)

    write(*,*) day
    do j = 1,np-1
        year(j)=day(j)/10000
        tmp = mod(day(j), 10000)
        month(j) = tmp/100
        date(j) = mod(tmp,100)
        ! just to see what we get.
        write(*, *) day(j), year(j), month(j), date(j)
    end do
    !write(*,fmt='(i4)')year
    !1 format(I4)
    !write(*,*)year

    return
    stop
end program

感谢IanH的评论,最新版本的fortran包含了一个新的单元选项,用于为程序员处理IO单元号。这使您无需为单元号定义命名常量。如果您不使用最新版本(某些公司不经常升级),则中有一个可供使用。

您可以使用格式化读取来显式拉出每个字段:

integer year,month,day,rain

...

read(1234,'(i4,i2,i2,i3)')year,month,day,rain

在您的代码中,您使用的是
i6
,因此
day(i)
包含类似于'194805'的内容,然后
rain(i)
从行的其余部分读取(即“date”整数的最后两位,一个空格和另一个整数)。我不知道
f5.2
格式是如何处理的,但它不可能是您想要的)

您可以使用格式化读取来显式拉出每个字段:

integer year,month,day,rain

...

read(1234,'(i4,i2,i2,i3)')year,month,day,rain
在您的代码中,您使用的是
i6
,因此
day(i)
包含类似于'194805'的内容,然后
rain(i)
从行的其余部分读取(即“date”整数的最后两位,一个空格和另一个整数)。我不知道
f5.2
格式如何处理它,但它不可能是您想要的)

其他两个答案的“混合”方法是首先将数据读入缓冲区,然后将其拆分为整数

character(50) buf
integer year, month, day, rain

read( 10, * ) buf, rain
read( buf, "(i4,i2,i2)" ) year, month, day

! or equivalently
! read( buf(1:4), * ) year
! read( buf(5:6), * ) month
! read( buf(7:8), * ) day
这里,列表定向I/O用于跳过第一列之前可能的空格,而整数是基于宽度提取的。此外,例如,在第一个read语句之后插入
if(buf(1:1)==“#”)循环,可以跳过以“#”(如果有)开头的注释行。

其他两个答案的“混合”方法是先将数据读入缓冲区,然后将其拆分为整数

character(50) buf
integer year, month, day, rain

read( 10, * ) buf, rain
read( buf, "(i4,i2,i2)" ) year, month, day

! or equivalently
! read( buf(1:4), * ) year
! read( buf(5:6), * ) month
! read( buf(7:8), * ) day
这里,列表定向I/O用于跳过第一列之前可能的空格,而整数是基于宽度提取的。此外,注释行以“#