我需要从表中读取一些值。这些是前五行,让您了解它应该是什么样子:
1 + 3 98 96 1
2 + 337 2799 2463 1
3 + 2801 3733 933 1
4 + 3734 5020 1287 1
5 + 5234 5530 297 1
我感兴趣的是每行的前四列。我需要将这些读入数组。我使用了以下代码:
program ----
implicit none
integer, parameter :: totbases = 4639675, totgenes = 4395
integer :: codtot, ks
integer, dimension(totgenes) :: ngene, lend, rend
character :: genome*4639675, sign*4
open(1,file='e_coli_g_info')
open(2,file='e_coli_g_str')
do ks = 1, totgenes
read(1,100) ngene(ks),sign(ks:ks),lend(ks), rend(ks)
end do
100 format(1x,i4,8x,a1, 2(5x,i7), 22x)
do ks = 1, 100
write(*,*) ngene(ks), sign(ks:ks),lend(ks), rend(ks)
end do
end program
程序结束时的循环是打印前100个条目以测试它们是否正确读取。问题是我得到了这个垃圾(第四行是问题):
1 + 3 757934891
2 + 337 724249387
3 + 2801 757803819
4 + 3734 757803819
5 + 5234 757935405
显然,第四栏已经过时了。事实上,我无法在我正在阅读的文件中的任何位置找到这些值。我正在为Ubuntu 12.04使用gfortran编译器。如果有人能指出我正确的方向,我将不胜感激。我确信我可能会遗漏一些非常明显的东西,因为我是Fortran的新手。
答案 0 :(得分:2)
Fortran格式(传统上,有些新东西我不会在这里讨论)固定格式,也就是说,它们最适合具有固定列的文件格式。即列N始终从字符位置M开始,没有ifs或buts。如果您的文件格式更像“自由格式”,即列由空格分隔,则使用列表格式化读取数据通常更容易,更健壮。也就是说,尝试将读取循环作为
do ks = 1, totgenes
read(1, *) ngene(ks), sign(ks:ks), lend(ks), rend(ks)
end do
另外,作为一般建议,在打开自己的文件时,从单元10开始,然后从那里向上移动。 Fortran实现通常使用一些低编号单元用于标准输入,输出和错误(常见的选择是单元1,5和6)。你可能不想重定向那些。
PS 2:我没有尝试过你的代码,但似乎你在sign变量中有一个边界溢出。它被声明为长度为4,但是你分配给索引ks,它一直到totgenes。当您在Ubuntu 12.04上使用gfortran(即gfortran 4.6)时,使用选项“-O1 -Wall -g -fcheck = all”开发编译时