1

私のデータは次のようになります

-3442.77 -16749.64 893.08 -3442.77 -16749.64 1487.35 -3231.45 -16622.36 902.29 

....。

159*2539.87 10*0.00 162*2539.87 10*0.00 

つまり、1行あたり7または8の実数で開始し、次に(終わりに向かって)1593.87の値が159、0の値が10、2539.87の値が162などになります。これは、以前のバージョンのようにスペースを節約する方法のようです。このファイル形式は、通常の1行あたり6リアルでした。

1行に7個か8個の数字があるかわからないため、すでにデータを文字列に読み込んでいます。したがって、*を含む線を簡単に見つけることができます。しかし、それではどうしますか?配列に割り当てる前に、各*の場所を特定してから、前の整数と後の実際の値を特定する必要があると思います。私は何かが足りないのですか?

4

2 に答える 2

3

行を読んでください。空白で区切られたトークンに分割します。*それを持つ in トークンをスペースに置き換えます。次に、アスタリスクがあるかどうかに応じて、文字列から 1 つまたは 2 つの値を読み取ります。サンプルコードは次のとおりです。

REAL, DIMENSION(big) :: data
CHARACTER(LEN=40) :: token
INTEGER :: iptr, count, idx
REAL :: val

iptr = 1
DO WHILE (there_are_tokens_left)
  ... ! Get the next token into "token"
  idx = INDEX(token, "*")
  IF (idx == 0) THEN
    READ(token, *) val
    count = 1
  ELSE
    ! Replace "*" with space and read two values from the string
    token(idx:idx) = " "
    READ(token, *) count, val
  END IF
  data(iptr:iptr+count-1) = val  ! Add "val" "count" times to the list of values
  iptr = iptr + count
END DO

ここでは、トークンの長さを任意に 40 文字に設定しました。入力ファイルで期待される内容に応じて調整してください。

ところで、完全を期すために、繰り返し値を値/繰り返し回数のペアに置き換えることで何かを圧縮するこの方法は、ランレングス エンコーディング(RLE) と呼ばれます。

于 2012-07-30T14:46:22.950 に答える
1

入力データは、リスト指示入力に適した形式で書き込まれている可能性があります (READ ステートメントの形式指定は単に「*」です)。リスト指示入力は、ご覧のように r*c 形式をサポートしています。ここで、r は繰り返し回数で、c は繰り返される定数です。

入力項目の総数が事前にわかっている場合 (おそらく、そのプログラム用に修正されているか、ファイル内の以前のエントリによって定義されている可能性があります)、ファイルの読み取りは次のように簡単です。

REAL :: data(size_of_data)
READ (unit, *) data

たとえば、例に示されている最後の行の「size_of_data」は、159+10+162+10 から 341 である必要があります。

リスト指示入力を使用すると、データは複数のレコード (複数行) にまたがることができます。各行にいくつの項目があるかを事前に知る必要はありません。データの次の「ブロック」に表示される項目の数だけです。

リスト指示入力には、このような他の「機能」がいくつかあります。そのため、それを念頭に置いて書かれていない「任意の」入力を解析するためにそれを使用することは一般的に良い考えではありません - 代わりに明示的なフォーマット指定を使用してください (事前にわからない場合は、入力フィールドの幅に合わせてその場でフォーマット仕様を作成する必要がある場合があります)。

READ ステートメントの前に項目数がわからない (または計算できない) 場合は、自分で行を解析する必要があります。

于 2012-07-30T21:34:52.213 に答える