Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.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
File io 无需提前阅读自由格式_File Io_Io_Fortran - Fatal编程技术网

File io 无需提前阅读自由格式

File io 无需提前阅读自由格式,file-io,io,fortran,File Io,Io,Fortran,在给定的文件记录中,我首先需要读取前两个整数元素,然后读取行的其余部分(大量实数元素),因为赋值依赖于前两个。假设前两个整数元素的格式没有很好地定义 解决问题的最佳方法可能是: read(unitfile, "(I0,I0)", advance='no') ii, jj read(unitfile,*) aa(ii,jj,:) 但在我看来,gfortran中不允许使用“(I0)”规范 基本上,在unitfile中读取的文件可能类似于: 0 0 <floats> 0 1

在给定的文件记录中,我首先需要读取前两个整数元素,然后读取行的其余部分(大量实数元素),因为赋值依赖于前两个。假设前两个整数元素的格式没有很好地定义

解决问题的最佳方法可能是:

read(unitfile, "(I0,I0)", advance='no') ii, jj
read(unitfile,*) aa(ii,jj,:)
但在我看来,gfortran中不允许使用“(I0)”规范

基本上,在unitfile中读取的文件可能类似于:

0   0    <floats>
0   10   <floats>
10   0    <floats>
100   0    <floats>
100   100    <floats>
0
0   10   
10   0    
100   0    
100   100    
使用任何类似fortran的固定字段格式规范都很难读取


有没有其他方法可以解决这个看似微不足道的问题?

这将应用字符串操作来获取各个组件,并用空格
'
和/或制表符(
char(9)
)分隔:

对于.txt中的文件
,例如:

1 2 3.0 4.0 5.0
这导致

./a.out 
   3.00000000       4.00000000       5.00000000

注意:这只是一个简单的例子,请根据您的需要进行调整

[这个答案已被大幅修改:原来的答案不安全。感谢IanH指出这一点。]

当我负担得起的时候,我通常会尽量避免使用非列表导向的格式化输入。对于字符串解析,已经有了一个非常通用的答案,但我将提供一些关于更简单设置的建议

当您对信任输入感到放松时,例如当格式有点棘手时(或者您很乐意将其留给编译器的边界检查),您可以使用

read(unitfile, *) ii, jj, aa(ii, jj, :)
或者,如果数组部分比前两列直接给出的更复杂,那么它可以是表达式,甚至是函数

read(unitfile, *) ii, jj, aa(fi(ii,jj), fj(ii,jj), :fn(ii,jj))
使用
纯整数函数fi(ii,jj)
等,这些函数甚至有可能进行范围验证(例如,返回大小为0的部分)

在更一般的情况下,但保持列表定向,可以为实际变量使用缓冲区

read(unitfile, *) ii, jj, buffer(:) ! Or ... buffer(:fn(ii,jj))
! Validate ii and jj before attempting to access aa with them
aa(.., .., :) = buffer
缓冲区大小合适的地方

您首先考虑的方法表明您对行的结构(包括长度)有一些合理的想法,但是当
ii
jj
中的real数未知,或者类型(不允许多态读取)未知时,事情确实变得棘手。此外,如果一个人对验证输入非常敏感,甚至对错误提供有意义的详细用户反馈,这不是最佳选择


最后,
iostat
有帮助。

i0
不允许在gfortran中读取文件,但肯定可以用于写入文件。你试过类似i3的东西吗?好的:谢谢@Kyle。不,它不起作用i3:看最后一个例子:您将无法正确读取第二个元素。。。。然而,我希望找到最普遍的解决方案。那么你的选择是要么使用@AlexanderVogt的将行作为字符串读取&必要时重复,要么使用不同的编译器。我更改了代码并使用
gcc
fprintf(fp,%d%d%f%f%f\n),I,j,(double)(I+j),(double)(I-j),(double)(j-I));
)编写文件,并使用
ifort
读取它,使用
read(10'(i0,i0'),advance='no'时没有任何问题)
@KyleKanos I0在输入格式规范中不是标准的F2008。列表定向输入可能适合内部用途,您可以很好地控制输入的质量,但对于一般用户提供的输入,它在验证和其他“令人惊讶”的功能方面存在严重缺陷。谢谢。我已经用gfortran测试了最简单的
读取(unitfile,*)ii、jj、aa(ii、jj,:)
,但我不确定它是否正常工作。@gluke您想读取的real数有多大?另外,
aa
的尺寸是多少?还有,它是否可以在一个较小的情况下工作/失败,您可以将其粘贴到这里?@francescalus我终于按照您的建议使用一个类似缓冲区的数组解决了这个问题,使用自由格式,并在下一步进行赋值。问题还在于,我不知道需要读取多少条记录,也就是说,我还必须使用
iostat
read(unitfile, *) ii, jj, buffer(:) ! Or ... buffer(:fn(ii,jj))
! Validate ii and jj before attempting to access aa with them
aa(.., .., :) = buffer