AIと戦って、あなたの人生のリスク診断 >>

fortranのファイル入出力のopen文で、パスを指定せずファイル名を指定すると、EXEのあるフォルダにそのファイルが作られますが、次の例は、サブフォルダOUTをあらかじめEXEのあるフォルダに作っておき、そこに、計算結果を判断してファイル名をvmax,timeと指定して出力した例です。この場合、サブフォルダOUTも、計算結果に応じてプログラム内で名前を指定したいのですが、できるのでしょうか。
例: open (10,file='./out/vmax.csv')
open (11,file='./out/time.csv')

A 回答 (2件)

環境をお書きになれていないので動作保証はいたしませんが。


# f90, f95 では確認しましたが。
このように書けばよろしいのではないでしょうか?

character(len=80) filename1
character(len=80) filename2
character(len=80) dirname
(ディレクトリ・ファイル名を決める処理)
open(10,file=trim(dirname)//'/'//trim(filename1))
open(11,file=trim(dirname)//'/'//trim(filename2))

# マニュアルをご覧になることをお薦めします。
    • good
    • 1
この回答へのお礼

早々のご回答、ありがとうございます。
早速、試してみます。

お礼日時:2008/04/13 20:15

出来ます。



file= の後は文字列定数じゃなくて文字列式も書けます。
    • good
    • 0
この回答へのお礼

早々のご回答、ありがとうございます。
早速、試してみます。

お礼日時:2008/04/13 20:14

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QFortranのOPEN文

OPEN(2,FILE='../data/'//FNAME//'c.dat')
というOPEN文についての質問です.このOPEN文のファイル名の指定FILE=' 'のところがわからないので,教えていただきたいのです.
ドット二つ(..)とスラッシュ1本(/),二本(//)の意味など,わかる方よろしくお願いします.

Aベストアンサー

スラッシュ二本(//)は文字列の結合演算子です。

FNAMEはCHARACTER宣言された文字列変数のはずです(FORTRANの仕様だとそれ以外に考えようがない)。
で、FNAMEに'hogehoge'と入っていれば、

FILE='../data/'//FNAME//'c.dat'='../data/'//'hogehoge'//'c.dat'='../data/hogehogec.dat'

ということで、オープンするファイルは../data/hogehogec.datとなるわけです(よけいな話だけど、'c.dat'は'/c.dat'じゃないですか)。

ドット二つ(..)は一階層上(親ディレクトリといいます)を意味します、ルートでは(ルートは一番もと)ではありません。

あと、FORTRANでは、一桁のファイル番号には、5はSYSIN(昔だったらパンチカード)、6はSYSOUT(昔ならラインプリンタ、今だったらコンソール)など、特別な役割を持たせてきた歴史があります。できれば、一桁の番号は避けた方が賢明でしょう。

QFortran:列数の分からないデータの読み込み

列数の分からないcsvファイルを想定して、配列を用いて読み込むプログラムを作成しようと考えています。

試しに十分に大きい1次元配列を用いてデータを読みこむプログラムを作成したところ
1行目読み込み時に行をまたいでデータを読み込んでしまいました。

なんとか、各行のデータだけを読み取る方法はないでしょうか?

よろしくお願いします。

ちなみにプログラムの内容、入力データ、出力結果は次の通りです。

・プログラム
implicit none
integer a(5),i
open(10,file='a.csv',status='old')
read(10,*)(a(i),i=1,5)
write(*,*)(a(i),i=1,5)
close(10)

・入力データ
    1,2,3,4
    5,6,7,8
    9,1,2,3

・出力結果
    1 2 3 4 5

Aベストアンサー

ちょっと強引かもしれないけど、

implicit none
integer a(5),i
character(80) line
open(10,file='a.csv',status='old')
read(10,'(a)') line
read(line,*,end=1)(a(i),i=1,5)
1 write(*,*)(a(i),i=1,5)
close(10)
end

Qfortranでデータの抜き出しをしたい

プログラムは、ド素人ですが急用です。
以下のようなCSVファイルがあります。
ido,keido,point
134.603057155416,34.1005169871047,1.07
134.603270155368,34.1005169871253,0.9
134.603499155317,34.1005129871483,0.76
134.603713155269,34.100512987169,0.54
134.604354155125,34.1005059872324,0.19
134.604567155077,34.100505987253,0.39
134.604796155026,34.100501987276,0.44
このようなものが100000個続く。
_________________________
データ数が100000個があります。
これらから、例えば、0以上0.5未満でido,keido,pointを
抜き出して、新たなCSVファイルを形成したいのです。
上の中なら、
134.604354155125,34.1005059872324,0.19
134.604567155077,34.100505987253,0.39
134.604796155026,34.100501987276,0.44
だけが抽出されたものです。

イメージとしては、(ファイル名は適当です。)
OPEN (5,FILE='motod.csv', status='old')
OPEN (5,FILE='newd.csv')
do 10 i=1,100000
READ(5,*) ido,keido,atai
IF(atai.GE.0.00).and.IF(atai.LT.0.50)then
WRITE(5,*)ido,keido,atai
10 continue
  stop
END
になりますが、配列などが必要な気がします。

新たにお示しいただくか、継ぎ足したプログラムをお示しください。
また、今後のために参考になりそうなサイトもご紹介いただけると
幸いです。

空白がおかしいところがあろうかと思いますが、
よろしくお願いいたします。

プログラムは、ド素人ですが急用です。
以下のようなCSVファイルがあります。
ido,keido,point
134.603057155416,34.1005169871047,1.07
134.603270155368,34.1005169871253,0.9
134.603499155317,34.1005129871483,0.76
134.603713155269,34.100512987169,0.54
134.604354155125,34.1005059872324,0.19
134.604567155077,34.100505987253,0.39
134.604796155026,34.100501987276,0.44
このようなものが100000個続く。
_________________________
データ数が100000個があり...続きを読む

Aベストアンサー

書かれているプログラムに対して気が付いたことをあげておきます。

型宣言を最初にしておくべきでしょう。
宣言文無しでは、iやkは整数型とみなされます。
real*8 ido,keido,atai

装置番号に5の使用は避けた方がよいと思います。
一般に標準入力として使用されています。
標準出力として使われる6も同様の理由で避けた方がよいです。
また、入力と出力の装置番号は一緒にしない方がよいと思います。
Fortran77の固定形式を使うのであれば、10から99までの数字を使って下さい。
OPEN (10,FILE='motod.csv', status='old')
OPEN (20,FILE='newd.csv')
...
READ(10,*) ido,keido,atai
...
WRITE(20,*)ido,keido,atai

読み込むcsvファイルの1行目に
ido,keido,point
という情報があれば、これは読み込む必要はないのでdo loopに入る前に空読みします。
read(10,*)
do 10 i=1,100000

if文でandを使うのであれば、
IF(atai.GE.0.00 .and. atai.LT.0.50)then
です。

出力にコンマ区切りが必要であれば、
WRITE(20,*)ido,',',keido,',',atai
とします。フォーマット文を使っても同様のことはできます。

stopの前に全角スペースが入っています。
コンパイラにもよりますが、一般にコメント文以外で全角文字を使うとコンパイルできなくなります。

特に配列は必要ありません。

質問とは直接関係ありませんが、コメント
うまく行かない場合はエラーメッセージを読みながら試行錯誤してください。
短いプログラムでは、コンパイルエラーをしっかり読めば簡単にデバグできます。
また、プログラムを勉強するのであれば、ネットも利用するのも1つの手段だとは思いますが、例題がたくさん載っている良書を参考にするのも良いと思います。

書かれているプログラムに対して気が付いたことをあげておきます。

型宣言を最初にしておくべきでしょう。
宣言文無しでは、iやkは整数型とみなされます。
real*8 ido,keido,atai

装置番号に5の使用は避けた方がよいと思います。
一般に標準入力として使用されています。
標準出力として使われる6も同様の理由で避けた方がよいです。
また、入力と出力の装置番号は一緒にしない方がよいと思います。
Fortran77の固定形式を使うのであれば、10から99までの数字を使って下さい。
OPEN (10,...続きを読む

QFortran90/95の出力方法について

Fortran90/95の出力方法について
Fortran95において,変数の値をwrite文で出力した後に改行しない方法を教えてください.
具体的には次のProgram reiを用いて質問します.
program rei
implicit none
integer i, n
read(*,*) n
do i = 1, n
write(*,*) i
end do
end
このプログラムを実行させnに3を代入すると次のように表示されます.
1
2
3
しかし,私としては次のように改行せずに表示させたいのです.
1 2 3
また,諸事情により配列は使用しません.
プログラムをどのように改良すればよいのでしょうか.教えてください.

Aベストアンサー

先程のURLに「18.3 数値と文字の変換を行う方法」という章がありますが。
数値を文字列に変換しても出力されませんでしょうか?

Qfortranでの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でやらなければならなくなって困っています
どなたかよろしくお願いします

Aベストアンサー

一次元配列にするなら
read(*,*) (a1(i),i=1,15)

二次元配列にするなら
read(*,*) ((a2(i,j),i=1,5),j=1,3)

Qfortranでのcsvファイルを出力する方法

fortranでコンマ切りテキストファイル(CSVファイル)を
出力する方法をご存知の方、いらっしゃいませんでしょうか?


私が使用した処理系(intel fortran 8.0 for Windows)で

write(600,*)1.4,',',2.33,',',30.11

というコードを実行させると
fort.600 というファイル名のテキストファイルが生成されて
中身は

___1.400000_____,___2.330000_____,___30.11000____

となります。( _ は半角空白を意味します。)
私が欲しいのは余計な空白の入っていない

1.4,2.33,3.11

または

1.400000,2.330000,30.11000

という出力なのですが、どのような書式指定をすれば
これが可能なのでしょうか?

全くのfortran初心者です。よろしくご教示ください。

Aベストアンサー

汎用的な方法は、#2さんのように文字列として書き出して、adjustlやtrimを使って空白を取るのでしょうが、Intel Fortran8.0ならば以下のようなformatでできます。
write(600,10) 1.4,',',2.33,',',30.11
10 format(f0.6,a1,f0.6,a1,f0.6)
マイナス記号があっても問題ないです。書式幅が0の指定はIとFに使えます。なかなか便利ですよ。ちなみにConpaq Visual Fortranでも使えます。

QFortranで文字の読み込み&書き込み

こんばんは。

FORTRANでとあるデータを処理しているのですが、
そこでひとつ分からないことがあるので質問します。
ご存知の方、ご教示願えないでしょうか。

以下、質問内容
------------------------------------
「aaaa_50」という文字列から、「_50」のみの文字列を抜き出したい。
具体例から説明しますと、
1 parameter A
2 read (10,*) A <-- Aは「aaaa_50」という文字列。
3 write (10,*) A <-- このままでは「aaaa_50」を書き込みます
------------------------------------
確か2行目と3行目の間に何らかの処理を書けば「_50」の文字列が
表現出来たと思うのですが・・・

説明も分かりにくいかもしれませんが宜しくお願いいたします。

Aベストアンサー

>parameter A
>read (10,*) A <-- Aは「aaaa_50」という文字列。
>write (10,*) A <-- このままでは「aaaa_50」を書き込みます

まず、parameter分で宣言した領域には、一般のFORTRANコンパイラだと読み込めないはず
また、通常は読み込んだ順編成のデバイス10にはそのままだと(rewindやreopenすれば別ですが)書きこめないと思います(コンソールは別なので、10をCONデバイスで開けば可能かな)

また、"aaaa_50"のaaaaの部分は必ず4桁なのでしょうか、それとも、アンダースコア"_"をサーチしてそれ以降を生かしたいのかで話は変わります。

固定で良いなら、部分文字列を使えば十分でしょう。
charater A*7
read (*,*) A
write (*,*) A(5:7)

あるいは
read (*,"(4x,a3)") A
write (*,*) A

のようにaaaaの部分を飛ばしてしまえばよいのでは
_で判断するのであれば、一行では無理

>parameter A
>read (10,*) A <-- Aは「aaaa_50」という文字列。
>write (10,*) A <-- このままでは「aaaa_50」を書き込みます

まず、parameter分で宣言した領域には、一般のFORTRANコンパイラだと読み込めないはず
また、通常は読み込んだ順編成のデバイス10にはそのままだと(rewindやreopenすれば別ですが)書きこめないと思います(コンソールは別なので、10をCONデバイスで開けば可能かな)

また、"aaaa_50"のaaaaの部分は必ず4桁なのでしょうか、それとも、アンダースコア"_"をサーチしてそれ以降を生...続きを読む

Qfortranの限界って・・・

こんにちは。
プログラミングはFORTRANくらいしかやった事のない上にあまり得意ではありません。

現在、3列に並ぶ237万行ほどのデータを扱っています。
この3列目のみ、つまり237万個の数字を、
1行あたり14個で並び替えしたいと思っています。
FORTRAN使用です。OSはWinXPです。

ところが、
読み込む時点で237万行のデータ(約1GB)が読み込めません。
テストで数行の軽いデータならうまく回ります。

237万行のデータでは回らないのは、データの行数に限度があるためなのでしょうか?
それとも単純なプログラムミス?
どなたかお詳しい方、ご教授お願いします。


もし、OSのせいだとしたら、LINUX等ではうまく回るのでしょうか?
その場合、WinとLINUXではプログラミングどう違うかも教えて頂けないでしょうか?
WinのプログラムはLINUXではそのまま動きませんでしたもので・・・

宜しくお願いします。

Aベストアンサー

#4です

補足で大体のことがわかりました。こんな感じでしょうか、一例を挙げてみます。
私はFORTRANは77で引退したので、77で書きます。コメントはコンパイラ通らないのでご注意。
ここではシンプルに書きますが、実際は、もう少しエラーチェックなどをした方が良いでしょう。

   CHARACTER*30 STRING
   REAL*4 DATA(3)
   INTEGER*4 IDATA(14)

   OPEN(10,FILE='HOGE.TXT',STATUS='OLD')
   OPEN(20,FILE='OUT.TXT',STATUS='NEW')

  1 CONTINUE
   NDATA=0  データのカウントを初期化
   DO 5 LOOP=1,15002  15002回のループ
   READ(10,'(A30'),END=9) STRING  データを読み、ファイル終端でループ脱出
   if(LOOP .GT. 1) THEN  1レコード目は読み飛ばして2レコード目以降を処理
    READ(STRING,'(3F10.1) DATA  数値を取り出し
    NDATA=NDATA+1  データのカウントを増やす
    IDATA(NDATA)=INT(DATA(3)*10000.+0.1)  整数化
    IF(NDATA .EQ. 14) THEN  14個読んだら書き出す
     WRITE(20,'(14I5)') IDATA
     NDATA=0  データのカウントを初期化
    ENDIF
   ENDIF
  5 CONTINUE
   IF(NDATA .GT. 0) THEN  15001/14だとあまりが出るけど書くのかな
    WRITE(20,'(14I5)') (IDATA(1),I=1,NDATA)
    NDATA=0
   ENDIF
   GO TO 1
  9 CONTINUE
   IF(NDATA .GT. 0) THEN  読み終わりでデータのあまり対策
    WRITE(20,'(14I5)') (IDATA(1),I=1,NDATA)
    NDATA=0
   ENDIF
   CLOSE(10)
   CLOSE(20)
   STOP
   END

こんな感じでしょうか、久々のFORTRANで自信がないけど。
大きな勘違いをしているようならご指摘ください
    

#4です

補足で大体のことがわかりました。こんな感じでしょうか、一例を挙げてみます。
私はFORTRANは77で引退したので、77で書きます。コメントはコンパイラ通らないのでご注意。
ここではシンプルに書きますが、実際は、もう少しエラーチェックなどをした方が良いでしょう。

   CHARACTER*30 STRING
   REAL*4 DATA(3)
   INTEGER*4 IDATA(14)

   OPEN(10,FILE='HOGE.TXT',STATUS='OLD')
   OPEN(20,FILE='OUT.TXT',STATUS='NEW')

  1 CONTINUE
   NDATA=0  データ...続きを読む

QFORTRAN で出力した文字の 左寄せについて

C Pad for Salford FTN77というコンパイラを使っております。
下記の様にOPENで開いてCLOSEでとじたTEXT文についてですが…

WRITE(*,*) '入力した数に1プラスされます。'
READ (*,*) A
B=A+1
OPEN(UNIT=10,FILE='C:\001.txt')
WRITE(10,100) '入力したのは',A
WRITE(10,100) '1たすと',B
100 FORMAT(A)
CLOSE(10)
STOP

…計算もされず、左寄せにもなりません。
仮に「100 FORMAT(A)」を消して(10,100)を(10,*)にすると左寄せにはなりませんが 計算して結果は表示されます。

計算して結果を左寄せにするにはどうすればよいでしょうか。
ご存知の方、アドバイスをお願いします。

Aベストアンサー

私が知っているfortranは77なのでもしかすると違っているかもしれませんが、

先ず変数Aは型宣言がないので実数扱いになります。

B=A+1(正確に記述するなら1ではなく1.)
が計算されることからもそういえます。

つぎに、FORMAT(A)の中のAは文字型を出力する際にし要するものですので、変数の型が一致していません。だから出力されないのだと思います。またAの後に桁数を示す数字が必要です。

実数に対してはFORMAT(F8.1)とかFORMAT(E8.3)とかのFやEを使用する必要があります。

また数値型の場合プラスマイナスの記号が入ることから、正値の場合+記号が省略されて、代わりにブランクが出力されたと思います。すなわち1つ目はブランクになります。
FORMAT(F1.0)等とすると桁オーバーを意味する*が出力されます。

整数型にしておけば1桁の場合FORMAT(I1)としておけば、左の1桁目に数字が出ますが、2桁以上やマイナス値のある数字の場合この方法は使用できません。

ブランクを取りたい場合、文字型で出力しなければなりませんが、たしかfortranには数値型データを文字型データに変換するコマンドがありません。

他の方法もあるかもしれませんが、そこで、一度数値データとしてファイルに出力して、そのファイルから文字型データとして1文字ずつ読み取るという方法で私自身は対処していました。

たしかこんな感じでした。
CHARACTER*1 H(8) 文字型と配列宣言
WRITE (10,601) A
601 FORMAT(F8.2)
BACKSPACE(10)
READ(10,602) (H(I),I=1,8)
602 FORMAT(8A1)

この後H(I)がブランクなら出力しない、ブランクでなければ出力するという判定作業を行って、ブランク以外の値が入っているI番目から後ろの値全部を文字型出力をします。

記憶が薄いので、上のとおりしてもうまくいきませんかもしれませんが、数値データを文字型データにうまく変換してやればできると思います。

私が知っているfortranは77なのでもしかすると違っているかもしれませんが、

先ず変数Aは型宣言がないので実数扱いになります。

B=A+1(正確に記述するなら1ではなく1.)
が計算されることからもそういえます。

つぎに、FORMAT(A)の中のAは文字型を出力する際にし要するものですので、変数の型が一致していません。だから出力されないのだと思います。またAの後に桁数を示す数字が必要です。

実数に対してはFORMAT(F8.1)とかFORMAT(E8.3)とかのFやEを使用する必要があります。

ま...続きを読む

Qfortran77で複数のファイルの読み込み

fortran77で複数のファイルの読み込み

現在fortran77のプログラムを勉強しております。
ファイルが複数あり、すべてのファイルを読み込みたいのですが、ファイルの数がたくさんあるため、プログラムの行数が多くなってしまいます。
do ループで次々とファイルを開くプログラムを考えているのですが、思いつきません。
どなたか考え方でもいいので、教えてください。

ちなみに私が考えたプログラムは、


open(10,file='C:\FORTRAN\100.txt',status='old')
open(11,file='C:\FORTRAN\121.txt',status='old')
open(12,file='C:\FORTRAN\144.txt',status='old')
open(13,file='C:\FORTRAN\169.txt',status='old')
open(14,file='C:\FORTRAN\196.txt',status='old')
open(15,file='C:\FORTRAN\225.txt',status='old')
・・・。

これを do ループで次々に開くことを考えると、

character*3 A(10)
do 100 i=1,10
A=i*i
open(i,file='C:\FORTRAN\A.txt',status='old')
100 continue

・・・

みたいな感じです。
' 'の中の一部だけを変えたい場合のcharacter 文の使い方がいまいちよく分かりません。

fortran77で複数のファイルの読み込み

現在fortran77のプログラムを勉強しております。
ファイルが複数あり、すべてのファイルを読み込みたいのですが、ファイルの数がたくさんあるため、プログラムの行数が多くなってしまいます。
do ループで次々とファイルを開くプログラムを考えているのですが、思いつきません。
どなたか考え方でもいいので、教えてください。

ちなみに私が考えたプログラムは、


open(10,file='C:\FORTRAN\100.txt',status='old')
open(11,file='C:\FORTRAN\121.txt',status='old')
open...続きを読む

Aベストアンサー

> I変換の場合は、I3とか4I5のように表すことしかできないと理解しております。

I変換はrIw.mの形式です。
このうちrは反復数で,wは欄幅を意味します。どちらも正の整数です。
mは負でない整数で,欄の最小桁数を意味します。入力のときには無視されます。
ゼロでない最初の桁まで先行するゼロを必要な数だけ強制的に挿入します。
例えば4をI3.3で出力すれば004となりますが,I3で出力すればbb4となります。(bは空白の意味)
mを省略すればm=1と解釈されます。だから0をI3.0で出力すればbbbとなりますが,I3で出力すればbb0となります。

ついでに

> (本来は、装置番号が入るという風に理解しておりますので、「何となく」ですが)

外部ファイルに対しては,それと装置番号を結び付けるためにOPEN文が必要ですが,内部ファイル(文字変数など)に対してはOPENせずに直接に入出力が可能です。

また装置番号に対しては何も触れませんでしたが,5,6,7番には事前に標準入力,標準出力,標準エラーと接続されています。これらをOPEN文でファイルに割り当てることもできますが,元の接続先には再接続出来なくなるので自分のプログラムでは5,6,7番をOPENするのは避けた方が良いでしょうね。

> I変換の場合は、I3とか4I5のように表すことしかできないと理解しております。

I変換はrIw.mの形式です。
このうちrは反復数で,wは欄幅を意味します。どちらも正の整数です。
mは負でない整数で,欄の最小桁数を意味します。入力のときには無視されます。
ゼロでない最初の桁まで先行するゼロを必要な数だけ強制的に挿入します。
例えば4をI3.3で出力すれば004となりますが,I3で出力すればbb4となります。(bは空白の意味)
mを省略すればm=1と解釈されます。だから0をI3.0で出力すればbbbとなりますが,I3で出...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング