Fortranでのファイルからの読み込み

このQ&Aのポイント
  • Fortranでのファイルからの数値の読み込みについてお尋ねします。
  • NAGのFortran解説サイトでは、配列を全体書き出す例と配列全体を指定する方法について説明があります。
  • なぜ上側よりも下側が推奨されているのか、理由についてお教えください。
回答を見る
  • ベストアンサー

Fortranでのファイルからの読み込み

Fortranでのファイルからの数値の読み込みについてお尋ねします。 NAGのFortran解説サイトでは以下のような説明がありました。 ----- write (10,*) ((a(i,j),i=1,3),j=1,2) ! DO 形反復を用いて配列を全体書き出す例 write (10,*) a ! 配列全体を指定。現在はこの書き方が推奨されています ----- ここで下側が推奨されるとのことですが、下側はファイルの構造と格納される配列の構造を明示せず、上側はどこに格納するのか明確になっています。上側は相手(データ構造)が変わった場合、それに応じた読み込みができるという意味で対応の幅が広いように思うのですが、どうして下側が推奨されるのでしょうか。下側は場合によっては誤解したまま進んでしまいそうですが。  

質問者が選んだベストアンサー

  • ベストアンサー
  • f272
  • ベストアンサー率46% (8019/17139)
回答No.1

入出力を行う以前に配列の形状は明確に定まっているはずです。そこで定まっているものと入出力時に示されるDO 形反復の整合性をとる必要があります。 下のような書き方をしていれば,自動的にそれはなされますから,余計なことを考える必要がなくなりプログラムの品質が上がるでしょう。

skmsk1941093
質問者

お礼

回答ありがとうございます。データ作成サイドとプログラム作成サイドの分業を考えると、プログラムサイドがどんなデータでも読み込むように調整するよ、と言ってしまうと、データサイドはプログラムのことを無視して適当なデータを作ってしまうので、プログラムサイドはいつもデータのことを気にしないといけなくなります。 一方でプログラムサイドがそのようなサービスは全くやらないと宣言してしまうと、データサイドがそれに合わせてデータを作成するということですね。そこでは暗黙的にデータの構造が決まっているということになると思います。例えば10x10だと100個の数字ですが、ループの回り方で行が先か、列が先か、ということの了解がなされているということなのでしょうか。 ご説明をそういう風に受け取ったのですが。

その他の回答 (1)

  • f272
  • ベストアンサー率46% (8019/17139)
回答No.2

(1) 既にデータが出来上がっていて,それを読むしかないのであれば,プログラムサイドでデータ構造に合わせて読むようにしなければならないのは当然です。fortranでもそのようにすることは可能です。DO形反復を用いるのでもいいですし,transposeで転置するのも可能です。 (2) しかし,データ作成をこれから作成するのであれば,データ作成サイドで読みやすい構造にすることも当然でしょう。これが困難な場合には(1)と同様になりますが,「ループの回り方で行が先か、列が先か」に関しては内側のループが配列の左側の添え字になるのはfortran使いなら当然に知っています。そういうふうに読めるようにデータを作るのです。

関連するQ&A

  • fortranでのcsvファイルの読み込み

    fortranで例えば下のようなcsvファイルを読み込み、配列に格納したいのですが、どのようにすればよいでしょうか? 12.3,45.6,78.9,23.4,56.7 23.4,56.7,89.1,23.4,56.7 34.5,67.8,91.2,34.5,67.8 当方、CやJavaなどの別の言語は経験があるのですが、急遽fortranでやらなければならなくなって困っています どなたかよろしくお願いします

  • Fortran99で複数ファイルの読み込み

    Fortran99で有限要素法の解析プログラムを作成しています。 要素番号と節点番号、各節点の座標を三次元の配列にまとめて格納したく、 複数のcsvファイルを相互に参照しながら配列に読み込みたいと思っていますが、 その方法が分かりません。 具体的には、一つ目のファイル(ex1.csv)の中身が、 1 1 2 10 11 20 21 30 31 2 2 3 11 12 21 22 31 32 3 3 4 12 13 22 23 32 33 ........ と配列になっており、1列目が要素番号、2~8列目が節点番号としています。 二つ目のファイル(ex2.csv)の中身が、 1 0 0 0 2 5 0 0 3 10 0 0 4 15 0 0 5 20 0 0 ..... となっており、1列目が節点番号、2~4列目がそれぞれ、x, y, z座標となっています。 一つ目のファイルは、 open(10, file = 'ex1.csv', status = 'old', action = 'read', position = 'rewind') do ELEM = 1, MAXELEM read(10, *) (ELEMDATA(ELEM, m, 1), m = 1, 8) enddo close(10) と書き、全ての要素と節点番号を三次元配列の一、二次元目に読み込みました。 次に、ex1.csvの節点番号(2~8列目)の番号を読み取り、その番号をex2.csvの1列目 から探し出して、配列の三次元目に格納したいと思っています。 宜しくお願い致します。

  • 行数の変動にも対応したファイル読み込みのやり方

    学校でファイル読み込みの課題を今しているのですが、ファイルの行数が増えた場合にも対応していて、且つ無駄な領域を使わないようなファイル読み込みをするのに困っています。 流れとしては csvファイルから内容を読み込む ↓ カンマで分割し、構造体に格納 ↓ その格納した構造体を返す という動きをしたいのですが、構造体をmallocで動的にメモリ確保する時にも、行数の取得が必要になってきて・・・ 一度行数を調べてから、処理を行う方法を取るか、他のchar型配列か何かに一度全てを格納して、そのときにカウントした行数を使って構造体のメモリを動的に確保する・・・くらいまでは思いついたのですが、始め全てを格納する時点でもまた動的にメモリを格納する方法が思いつかなくて・・・・ やはりどこかで多めに領域を取り、そこに格納する手を使うしかないのでしょうか? ご教授お願いします。

  • 【fortran77】空行を含む数値データの読み込み

    fortran77でプログラムを書いています。 いま以下のような空行を含むデータファイルを読み込んで、プログラム中で計算し、その結果を別のファイルに書き出すものを作りたいと考えています。 1.0 1.1 1.2 1.3 1.0 1.4 1.5 1.6 2.0 2.1 2.2 2.3 2.0 2.4 2.5 2.6 3.0 3.1 3.2 3.3 3.0 3.4 3.5 3.6 *数字はあくまでも例です。 例えば、1列目が2.0で始まる箇所のみ取り出したいのですが、どうもデータの読み込みのところでエラーが起こっているようです。 open(1,file="data.dat") do i = 1,8 read(1,*) (a(i,j),j=1,4) enddo 空行や空白の読み飛ばしを行う方法を自分なりに調べてみて、open文にblankを指定するなどの方法があることはわかったんですが、いまいち使いかたがわからず立ち止まってしまいました。 よろしくお願いします。

  • 配列のファイル出力について

    fortranでできるファイルへの配列の出力をC言語でどのようにプログラムするか教えて頂きたいと思います。 2次元配列a(i,j)の出力はfortranでは以下のようなプログラムになります。 open(10,.省略...) ファイルを指定して開く do j=1,ny                ループj   write(10,'(100f10.3)') (a(i,j),i=1,nx) ループi+書き出し enddo                  ループjの最後尾  close(10)                ファイルを閉じる 100f10.3というのは小数点3桁の実数で10カラムで表現したものが100個並ぶという意味です。これと同じことをやるC言語プログラムを教えて頂きたいのですが。私の手元にある本にはやり方が載っていません。 C言語にはfortranのような数字のカラムを指定するようなフォーマットの調整などできるのでしょうか。よろしくお願いします。

  • 配列のファイルへの出力について

    fortranでできるファイルへの配列の出力をJAVAでどのようにプログラムするか教えて頂きたいと思います。 2次元配列a(i,j)の出力はfortranでは以下のようなプログラムになります。 open(10,.省略...) ファイルを指定して開く do j=1,ny                ループj   write(10,'(100f10.3)') (a(i,j),i=1,nx) ループi+書き出し enddo                  ループjの最後尾  close(10)                ファイルを閉じる 100f10.3というのは小数点3桁の実数で10カラムで表現したものが100個並ぶという意味です。これと同じことをやるJAVAプログラムを教えて頂きたいのですが。私の手元にある本にはやり方が載っていません。 JAVAにはfortranのような数字のカラムを指定するようなフォーマットの調整などできるのでしょうか。よろしくお願いします。 この質問は、C言語について以前質問したものですQNo.3590702。 JAVAだったらどうなるだろうと思ってお尋ねしています。

    • ベストアンサー
    • Java
  • ファイルからの読み込み 配列

    座標データの数値のテキストファイルから配列の中に座標値を格納したいのですが、int型のデータを読み込んで配列に格納するのは、どのようにプログラムを組めばよろしいのでしょうか?下のようにxzahyou.csvというファイルから配列Z[i]に格納したくて組んでみたら、 br = new BufferedReader(new FileReader("xzahyou.csv")); for(int i=0;i<X.length;i++){ String line = br.readLine(); X[i]=line; X[i] = line;のところで互換性がないと出てきました。int型の場合どのようにすればよろしいのでしょうか?教えてください。お願いします。

  • fortranのデータ読み込み

    fortranで下記の読み込みたいデータがあります。 j k R(j,k) L(j,k) 1 1 5 1 1 2 10 2 1 3 15 3 1 4 20 4 2 1 25 5 2 2 30 6 データが9000行あるので, do i=1,9000 read(10,*) j(i) k(i) enddo のような読み込み方だと配列が大きすぎてだめなんです。 他の方法を知っている方、教えていただけませんか。 よろしくお願いします。

  • FortranにあってCにない関数?について

    10年間Fortran90でプログラミングをしてきましたが、 C言語を使う必要があって、プログラムを書き直し中の者です。 入門書を数冊読んでいて疑問に思ったのですが、Fortranには、 A=SUM(B) と書けば、配列Bの全ての総和をAに返す、という関数があるのですが、C言語に同じような関数はないのでしょうか?(標準ライブラリに無いという事はないのでしょうか?) Fortranと比べてCは組み込み関数が少ないという印象を持ったのですが実際そうなのでしょうか? また、Fortanでは配列の和をとる時、 do i=0,n a(i)=b(i)+c(i) end do を一行で、 a(0:n)=b(0:n)+c(0:n) と書いても良いですし、もし定義されている全部の配列の要素が対象なら a=b+c と一行で書いても良いのですが、c言語では似たような書き方はできないのでしょうか? つまり、多次元配列を扱う時、Fortranでは単に「a=b+c」と書けば済むところを、Cでは for (i=0,i<=n,i++){ for (j=0,j<=n,j++){ for (k=0,k<=n,k++){ a[i][j][k]=b[i][j][k]+c[i][j][k]; }}} と書かなくてはいけないのか?と悩んでおります。 私がCの機能を知らないだけなのか、Cとはそうゆうことが出来ないのか、浅学なため判断できません。 ご教授ください、どうぞよろしくお願いいたします。

  • ファイル読み込みが上手くできません

    C言語初心者です。 現在、ファイルの情報を構造体に読込んで実行するプログラムを作成しております。 読込むファイルは700MBほど(行数は39900000行)となっており、1行ずつfscanfで読込んでいます。 400000行ごとに構造体に読込んで、処理を実行し、構造体に読込んだ全ての処理が完了したら、再度400000行読込んで・・・を繰り返すものになっております。 400000行ごとにしているためforループで100回まわすようにしているのですが、最後の1回(100回目のループ)で、99回目と同じ場所を読んできてしまいます。 つまり、最後の1回だけはファイルポインタが進んでいない状況になります。 コードは下記になります。 #define MAX_SIZE 400000 uint64_t i = 0; uint64_t fc = 0; int main(int argc, char *argv[]){ char w[] = "$write"; char r[] = "$read"; // ファイルを構造体へ格納 char filename[] = "TEST_READ_WRITE.txt"; struct TEST_DATA{ char cmd[10]; int addr; int bsize; }; FILE *fp; if ((fp = fopen(filename, "r")) == NULL){ printf("%s open error !\n", filename); exit(1); } for (int lp = 0; lp < 100; lp++){ struct TEST_DATA TD[MAX_SIZE]; // 構造体配列の宣言 for (fc = 0; fc < MAX_SIZE; fc++) { if (feof(fp)){ break; } else{ fscanf(fp, "%s %d %d\n", TD[fc].cmd, &TD[fc].addr, &TD[fc].bsize); } } while (i < MAX_SIZE - 1){ //ファイルから取得したデータによって処理を実行 if (strcmp(TD[i].cmd, w) == 0){ //書込み処理 } if (strcmp(TD[i].cmd, r) == 0){ //読み込み処理 } } printf("Finish!! \n"); } fclose(fp); return 0; } 読込むファイルはテキストデータで、 $write 25651496 152 $write 135878112 8 $read 1244848 16 のような感じのものが39900000行並んでいるものになります(数字はランダムです)。 最後の1回のみ上手くファイルポインタが進まない原因が分からずに困っています。 お気づきの方がいらっしゃいましたら、アドバイスをよろしくお願いします。

専門家に質問してみよう