没有提前阅读自由格式 [英] Read free format with no advance

查看:120
本文介绍了没有提前阅读自由格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



解决这个问题的最好办法可能是:

  read(unitfile,(I0,I0),advance ='no')ii,jj 
read(unitfile,*)aa(ii,jj,:)

但在我看来,(I0)规范在gfortran中是不允许的。 >

基本上,在unitfile中读取的文件可能是这样的:

  0 0< ;漂浮> 
0 10<浮点>
10 0<浮动>
100 0<浮动>
100 100<浮动>

这是很难用类似fortran的固定字段格式规范读取的。 b
$ b

有没有其他的方法可以解决这个问题,显然是微不足道的问题?解决方案

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



我通常会尽量避免格式化的输入,这是不是列表导向,当我能负担得起。字符串解析已经有了很好的答案,但我会提供一些简单设置的建议。



当您放松信任输入时,比如何时它只是格式化有点棘手(或者你很乐意把它留给你的编译器的边界检查),你可以用你的例子来处理例子:

pre code> read(unitfile,*)ii,jj,aa(ii,jj,:)

或者,如果数组部分比前两列直接给出的数组部分更复杂,可以通过表达式,甚至通过函数来​​获得。

  read(unitfile,*)ii,jj,aa(fi(ii,jj),fj(ii,jj),:fn(ii,jj))
/ pre>

纯整数函数fi(ii,jj)等等。在这些函数中进行验证(例如返回大小为0的部分)。

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

$ $ $ $ $ $读取(unitfile,*)ii,jj,buffer(:)!或... buffer(:fn(ii,jj))
!在尝试访问aa之前验证ii和jj
aa(..,..,:) = buffer

其中缓冲区大小合适。

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

最后, iostat 帮助。


In a given file record, I need to read the first two integer elements at first, and then the rest of the line (a large number of real elements), because the assignment depend on the first 2. Suppose the format of the first two integer elements is not really well defined.

The best way to solve the problem could be something:

read(unitfile, "(I0,I0)", advance='no') ii, jj
read(unitfile,*) aa(ii,jj,:)

But it seems to me the "(I0)" specification is not allowed in gfortran.

Basically the file read in unitfile could be something like:

0   0    <floats>
0   10   <floats>
10   0    <floats>
100   0    <floats>
100   100    <floats>

which is hard to be read with any fortran-like fixed field format specification.

Is there any other way to get around this, apparently trivial, problem?

解决方案

[This answer has been significantly revised: the original was unsafe. Thanks to IanH for pointing that out.]

I generally try to avoid doing formatted input which isn't list-directed, when I can afford it. There's already an answer with string parsing for great generality, but I'll offer some suggestions for a simpler setting.

When you are relaxed about trusting the input, such as when it's just the formatting that's a bit tricky (or you 're happy leaving it to your compiler's bounds checking), you can approach your example case with

read(unitfile, *) ii, jj, aa(ii, jj, :)

Alternatively, if the array section is more complicated than given directly by the first two columns, it can be by an expression, or even by functions

read(unitfile, *) ii, jj, aa(fi(ii,jj), fj(ii,jj), :fn(ii,jj))

with pure integer function fi(ii,jj) etc. There is even some possibility of having range validation in those functions (returning a size 0 section, for example).

In a more general case, but staying list-directed, one could use a buffer for the real variables

read(unitfile, *) ii, jj, buffer(:) ! Or ... buffer(:fn(ii,jj))
! Validate ii and jj before attempting to access aa with them
aa(.., .., :) = buffer

where buffer is of suitable size.

Your first considered approach suggests you have some reasonable idea of the structure of the lines, including length, but when the number of reals is unknown from ii and jj, or when the type (and polymorphism reading isn't allowed) is not known, then things do indeed get tricky. Also, if one is very sensitive about validating input, or even providing meaningful detailed user feedback on error, this is not optimal.

Finally, iostat helps.

这篇关于没有提前阅读自由格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆