- ベストアンサー
プログラムで数値データの読み込み方法についての質問
- プログラムで数値データを読み込む際に、小数点の位置が変わる場合のformat指定方法について質問です。
- format(f7.5, e8.2)やformat(e7.5, e8.2)といった指定を試しましたが、セグメンテーション違反が発生してしまいます。
- 正しいformat指定の方法をご教示いただきたいです。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
小数点の位置の変化とformatの指定に関してですが、入力データにちゃんと小数点(ピリオド)が入っていれば、f7.5でもf7.3でも構いません。それによって読み込んだ値が100倍になったりするわけではありません。というわけで普通はf7.0のように書きます。小数点がない場合はf7.3で読み込んだ値がf7.5で読み込んだときの100倍になるので注意が必要です。 それからEタイプで書かれている実数もわざわざEタイプでformatを指定する必要はありません。e8.2ではなくてf8.2でもf8.0でも大丈夫です。 つまり、実数の読み込みに関しては、fx.0(xは桁数)で済んでしまうことになります。 見方を変えれば、当初のformat文(f7.5,e8.2)でも正しいformatですので、桁数が合っていれば少なくとも最初のenergyとcountは正しく読めているはずです。 「セグメンテーション違反」が出るのは別の理由だと思われますので、もう少し詳しいソース、使用しているコンパイラ、コンパイル時のオプション、OSなどを示していただけたら回答してもらえるのではと思います。
その他の回答 (6)
- パんだ パンだ(@Josquin)
- ベストアンサー率30% (771/2492)
#1です。 >分けるという作業はとてもできないのです。 全部分けろと言っているのではなくて、簡単なファイルを用意し、それが読み込めるかどうかチェックしてみて欲しいという意味です。 たとえば、 1.11111 2.22222 3.33333 4.44444 を read(*,10) energy 10 format(f7.5) で読み込めるのか? 読み込めたなら、 1.11111 22.2222 333.333 4444.44 ならどうなるのか? と言う風に、順番に検討していけばエラーの原因が見えてくるのではないかと思ったのです。
- notnot
- ベストアンサー率47% (4900/10359)
>一行に >energy count energy count energy count >というように3組になっていて、それが15000列ほど続いています。 >それを >read(2,10) (E(i),C(i),i=1,NP)←NPはデータ数です。 >10format(f7.5,e8.2,f7.5,e8.2,f7.5,e8.2) >というふうに書きました。 もしかして、NPは3x15000にしてますか?ひとつのread文では1行しか読めない(少なくとも昔は)はずです。 do 10 n=1,NP,3 read(2,*) (E(i),C(i),i=n,n+2)I 10 continue でどうでしょう?
- 530529
- ベストアンサー率16% (86/521)
確か、入力数値に小数点が有ればそちらが優先されるので昔は符号、小数点、数値の合計のけた数だけ書いて、小数点以下の桁数は”0”としていました。 今回だとF7.0でよいかと思います。 あと、次の数値との間に1桁空いていますがそこは符号が来るとすれば、E9.2でどうでしょうか ? もし空いているところが空白なら1Xを間に入れて、 F7.0、1X、E8.2 (このときも、E9.0とかE8.0でもいいかも) こうかいていると大昔にパンチカードを使っていた頃によく間違えたのを思い出します。
補足
みなさんのご協力ほんとうにありがとうございます。 せっかくなのですがまだうまくいっていません。 実は質問のときには省略してしまったのですが、 読み込みたいデータというのは、 一行に energy count energy count energy count というように3組になっていて、それが15000列ほど続いています。 それを read(2,10) (E(i),C(i),i=1,NP)←NPはデータ数です。 10format(f7.5,e8.2,f7.5,e8.2,f7.5,e8.2) というふうに書きました。 編集記述子をいろいろ変えてみたのですがダメみたいです。
- notnot
- ベストアンサー率47% (4900/10359)
1行が16文字なのにformatで指定している長さの合計が15文字なのがまずそうに思います。 format指定せずに、 read(*,*) energy,count でどうでしょうか?
- osamuy
- ベストアンサー率42% (1231/2878)
シンプルにREADして、暗黙に型変換させるとか: REAL*8 energy REAL*8 count CHARACTER LINE(4)*17 DATA LINE(1) / '1.11111 1.00E+01' / DATA LINE(2) / '22.2222 2.00E+01' / DATA LINE(3) / '333.333 3.00E+01' / DATA LINE(4) / '4444.44 4.00E+01' / INTEGER i DO i=1,4 READ( LINE(i), * ) energy, count PRINT *, energy, count END DO END FSF-g77で試してます。
- パんだ パンだ(@Josquin)
- ベストアンサー率30% (771/2492)
10 format(f8.5,e8.2) か 10 format(f7.5,e9.2) にしてみてください。 だめなら、データを分けて、 1.11111 22.2222 333.333 4444.44 read(*,10) energy 10 format(f7.5) と 1.00E+01 2.00E+01 3.00E+01 4.00E+01 read(*,10) count 10 format(e8.2) で正常に読みこめるのかチェックしてください。
お礼
アドバイスありがとうございます。 しかし、データが450000個もあるので 分けるという作業はとてもできないのです。 まとめて読み込みたいと思っています。
お礼
ご指摘の通りでした。 FORMATだけにこだわっていたのですが、配列やサブルーチンなどが原因でした。 お蔭様でデータを読み込むことができましたのでこの場を借りてアドバイス下さった皆様にお礼申し上げます。