• 締切済み

ファイルの読み込みが上手くいかず困っています。

#include<stdio.h> #include<math.h> #include<time.h> #define i0 2 /*流体部分の最小格子番号*/ #define j0 2 #define k0 2 #define in 41 /*流体部分の最大格子番号*/ #define jn 41 #define kn 41 #define imax 44 /*境界を含めた格子の数*/ #define jmax 44 #define kmax 44 #define N 100000 void sabun(void); int i,j,k,n,pgosa,vgosa,x,y,z; double u[imax][jmax][kmax], v[imax][jmax][kmax], w[imax][jmax][kmax], p[imax][jmax][kmax]; double u2[imax][jmax][kmax], v2[imax][jmax][kmax], w2[imax][jmax][kmax], p2[imax][jmax][kmax]; double Vn=-1.0, a=10.0; /*初期値*/ double dt=0.001, dx=0.025, dy=0.025, dz=0.025, rei=250000.0; double dx2, dy2, dz2, po; main() { FILE *fpin,*fpout; clock_t start,end; start = clock(); /*時間計測開始*/ fpin=fopen("H-clock.dat", "r"); /*入力ファイル*/ if(fpin==NULL) { printf("入力ファイルのオープンに失敗しました"); return 0; } x=i-1; y=j-1; z=k-1; for(i=i0;i<=in+1;i++){ for(j=j0;j<jn+1;j++){ for(k=k0;k<kn+1;k++){ fscanf(fpin,"%d %d %d %.6lf %.6lf %.6lf %.6lf\n",&x,&y,&z,&u[i][j][k],&v[i][j][k],&w[i][j][k],&p[i][j][k]); printf("%d %d %d %.6lf %.6lf %.6lf %.6lf\n",x,y,z,u[i][j][k],v[i][j][k],w[i][j][k],p[i][j][k]); } } } 読み込みの部分のある部分まで載せているのですが読み込みの部分に問題が あると思うのですがどうすれば読み込んでくれるのか分かりません。ですので解決法を教えていただけると助かります、よろしくお願いします。

みんなの回答

  • Gotthold
  • ベストアンサー率47% (396/832)
回答No.3

fscanfの戻り値をちゃんと確認しましょう。 そうすれば、最初のfscanfで数値を3つしか読めていないことが分かります。 読めていないのは、書式指定がおかしいからだと思います。 fscanf(fpin,"%d %d %d %lf %lf %lf %lf\n",&x,&y,&z,&u[i][j][k],&v[i][j][k],&w[i][j][k],&p[i][j][k]); printf("%d %d %d %.6f %.6f %.6f %.6f\n",x,y,z,u[i][j][k],v[i][j][k],w[i][j][k],p[i][j][k]);

zeros121
質問者

お礼

書式設定がおかしいのが原因だったんですね。 まだまだ勉強不足のため理由が分からなかったのですがGottholdさんのおかげで解決できました。ありがとうございました。まだまだ勉強不足のためまた質問するかもしれませんがその時はまたお願いします。本当にありがとうございました。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

「読み込みの部分に問題があると思う」というのは, どうしてそのように思ったんでしょうか? できれば「このように読みこまれているはずが, 実際にはこのように読みこまれているので問題があると思った」のように書いてもらえると助かります.

zeros121
質問者

補足

データを読み込んでいるか確認するためにprintfで読み込んだデータを出力させた時に読み込ませたdatファイルの値とことなり出力された値がほとんど0で出力されていたからです。 最終行で本当は 41 41 41 0.000000 0.000000 0.000000 -5.641614 となるはずのところ 1 1 0 0.000000 0.000000 0.000000 0.000000 のように出力されていたからです。

回答No.1

読みこみたいデータのフォーマットは?

zeros121
質問者

補足

1 1 1 0.004223 0.004302 0.002611 -5.638806 1 1 2 0.004101 0.004277 -0.001024 -5.662546 1 1 3 0.004162 0.003904 -0.001774 -5.638171 1 1 4 0.003482 0.002582 -0.001253 -5.660216 1 1 5 0.003934 0.002219 -0.000749 -5.638055 1 1 6 0.003437 0.001163 0.000195 -5.659870 上のようなデータが41×41×41行あるdatファイルを読み込む感じです。 よろしくお願いします。

関連するQ&A

  • 初心者な質問その5

    ************************************************************************* void mmul(double a[],double b[],double c[],int imax,int jmax,int kmax){ int i,j,k; for(i=0;i<imax;i++){ for(k=0;k<kmax;k++){ c[(1)]=0.0; for(j=0;j<jmax;j++){ c[i*kmax+k] += a[(2)]*b[(3)] } } } } ************************************************************************* 行列の乗算を計算するプログラムです。 ⅰ,(1)~(3)に入る式 ⅱ,この関数mmulを使って下の行列を計算するプログラム についてお願いします。

  • 読み込んだデータの読み飛ばしが出来ずに困っています。

    1 1 1 0.004223 0.004302 0.002611 -5.638806 1 1 2 0.004101 0.004277 -0.001024 -5.662546 1 1 3 0.004162 0.003904 -0.001774 -5.638171 1 1 4 0.003482 0.002582 -0.001253 -5.660216 1 1 5 0.003934 0.002219 -0.000749 -5.638055 上記のように続くデータを読み込むところまでは出来ていのですが データの左側3行を読み飛ばすことが出来ずに困っています。 何かいいアドバイスをいただけると助かるのでよろしくお願いします。 for(i=i0; i<=in+1; i++) { for(j=j0; j<=jn+1; j++) { for(k=k0; k<=kn+1; k++) { fscanf(fpin,"%d %d %d %.6lf %.6lf %.6lf %.6lf", &x,&y,&z,&u[i][j][k],&v[i][j][k],&w[i][j][k],&p[i][j][k]); } } } データは読み込ませる部分は上記のように書いています。

  • datファイルの読み込み

    初歩的な質問ですみません。 今、819200行のファイルをfscanfで読み込んで配列に格納しているのですが、実行してみるとBus errorが出力されてしまい、うまく格納できません。どなたか至急教えてもらえませんか? ***************************ソース************************************************************ #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #define pi 3.1415926535 //円周率 #define FILE_SIZE 819200 #define FILE_NAME "test.dat" struct Data{ int time; double voltage; double velocity; double pressure; double trigger; }; int main() { int k,n,N,i=0,j; struct Data dat[FILE_SIZE]; FILE *fp1; FILE *fp2; if ((fp1 = fopen(FILE_NAME,"r")) == NULL) { printf( "file open error\n" ); exit(EXIT_FAILURE); } //データの読み込み while((fscanf(fp1, "%d %lf %lf %lf %lf",dat[i].time,dat[i].voltage,dat[i].velocity,dat[i].pressure,dat[i].trigger)) !=EOF ){ i++; } fclose(fp1); return 0; } ***************************************************************************************** ********************test.datファイル********************************************** -2.64316 2.329595 0.697657 0.001373 -4.861982 -2.64314 2.325628 0.671961 0.001984 -4.744793 -2.64312 2.320745 0.640333 0.001678 -4.659953 -2.64310 2.319829 0.634400 0.002289 -4.707866 -2.64308 2.319219 0.630449 0.002289 -4.699321 -2.64306 2.317082 0.616607 0.002594 -4.532387 . . . . . *********************************************************************************** 環境はmac osです。 よろしくおねがい致します。

  • 行列に関して。

    以下の行列を対角成分が最も大きくなるような プログラムをつくりたいのですが 0   1   4  3 7   0   1  -5 1    3   0   7 -2   4   4  -8 #include<stdio.h> #include<math.h> #include<stdlib.h> #define NUM 4 int main(){ /* 初期化 */ int i; /* ループ変数 (行)*/ int j; /* ループ変数 (列)*/ int k; /* ループ変数 */ int imax; /* 最大値のi成分 */ int jmax; /* 最大値のj成分 */ double nmax; /* 最大値を入れるための変数 */ double tmp; /* ソートのための一時的な変数 */ double eps = 1.0e-6; /* 判定値 */ double a[NUM][NUM] = { { 0.0, 1.0, 4.0, 3.0}, { 7.0, 0.0, 1.0, -5.0}, { 1.0, 3.0, 0.0, 7.0}, {-2.0, 4.0, 4.0, -8.0}}; /* 対象とする要素位置 = k */ for( k = 0 ; k < NUM ; k++ ){ /*対象とする要素位置 = k*/ nmax = 0.0;/* 初期化 */ imax = k;/* 初期化 0とは限らない */ jmax = k;/* 初期化 0とは限らない */ /* 1.絶対値の最大値を求める */ for( i = k ; i < NUM ; i++ ){ for( j = k ; j < NUM ; j++ ){ if(fabs(nmax) < fabs(a[i][j])){ nmax = a[i][j]; imax = i; jmax = j; /* 対象としている行列要素の中で,最大となる行列要素のi,j成分を探す */ /*ここに絶対値の最大値を求め、nmax、imax、jmaxに代入するプログラムを書く*/ /*絶対値の求め方、数学関数fabs(x)を用いる*/ } } } /* 2.行入れ換え */ if( k != imax ){/* 対象としている行と最大値を持つ行が同じなら,入れ替える必要が無い */ for( j = 0 ; j < NUM ; j++ ){ tmp=a[k][j]; a[k][j]=a[imax][j]; a[imax][j]=tmp;/* 対象としている行と最大値を持つ行との入れ替え */ /*ここに行の入れ替え行うプログラムを書く*/ } } /* 3.列入れ換え */ if( k != jmax ){/* 対象としている列と最大値を持つ列が同じなら,入れ替える必要が無い */ for( i = 0 ; i < NUM ; i++ ){ tmp=a[i][k]; a[i][k]=a[i][imax]; a[i][imax]=tmp;/*対象としている列と最大値を持つ列との入れ替え*/ /*ここに列の入れ替え行うプログラムを書く*/ } } } /* 結果の出力 */ for(i=0; i<NUM; i++){ for(j=0; j<NUM; j++){ printf("%5.1f ",a[i][j]); } printf("\n"); } /*ここに行列の表示プログラムを書く*/ return(0); } 上のぷろぐらむを実行しても、1個目のfor文の1ループ目で終了してしまい 1行目と、4行目を交換、4列目と1列目を交換した行列だけが表示されます。 結果が以下のような行列にするにはどう改善すればよいでしょうか? -8.0   -2.0  4.0  4.0 -5.0   7.0  1.0  0.0   3.0   0.0  4.0  1.0  7.0   1.0  0.0  3.0 です。

  • csvファイルの読み込み

    fscanf関数を用いて、csvファイルの内容を構造体のそれぞれのメンバに読み込んで表示させようとしているのですが、4列目以降が上手く読み込めません。初歩的な質問で申し訳ありませんがどなたか教えてください。 ****************************ソース************************************************ #include <stdio.h> #include <string.h> #include <stdlib.h> #define SIZE 64 #define FILE_NAME "view_001_McdlData.csv" #define FILE_SIZE 819200 struct Data{ int DataNo; int FrameNo; int SampleNo; char Digital; double voltage; double trigger; double C; double D; }; int main(int argc, char *argv[]) { FILE* fp,*fo, *fi; // ファイルポインタ用 int n, i, file_size; double time,vel[FILE_SIZE]; struct Data *dat; char buff[SIZE]; if ((fp = fopen(FILE_NAME,"r")) == NULL) { printf( "file open error\n" ); exit(EXIT_FAILURE); } fseek(fp, 0, SEEK_END); file_size = ftell(fp); dat = (struct Data*)malloc(file_size); printf("malloc address= %p, file size= %d\n", dat, file_size); fseek(fp, 0, SEEK_SET); i = 0; //データの読み込み while((fscanf(fp, "%d,%d,%d,%s,%lf,%lf,%lf,%lf",&dat[i].DataNo,&dat[i].FrameNo,&dat[i].SampleNo,&dat[i].Digital,&dat[i].voltage,&dat[i].trigger,&dat[i].C,&dat[i].D)) !=EOF ){ printf("%d %d %d %s %lf %lf %lf %lf\n",dat[i].DataNo,dat[i].FrameNo,dat[i].SampleNo,dat[i].Digital,dat[i].voltage,dat[i].trigger,dat[i].C,dat[i].D); i++; } fclose(fp); return 0; } ***********************************csvファイルの内容************************************ 0,1,0,0x3F,2.270000,0.000000,-1.000000,-1.000000 1,1,1,0x3F,2.260000,0.010000,-1.000000,-1.000000 2,1,2,0x3F,2.260000,0.010000,-1.000000,-1.000000 3,1,3,0x3F,2.260000,0.010000,-1.000000,-1.000000 4,1,4,0x3F,2.260000,0.010000,-1.000000,-1.000000 5,1,5,0x3F,2.260000,0.000000,-1.000000,-1.000000 ***************************************************************************************************

  • 配列のコピー

    BVA初心者です。 基礎の基礎なのですが、質問させていただけないでしょうか。 excel VBAで、いま画面に 12345678910 12345678910 12345678910 ・・・・・・ と、あります。 これと、同じ配列を、右端にも作りたいのですが、 ”A(i, 1) = A(i, JMAX + 1)” のような記述方法で、全体をコピーすることはできますか?(copyメソッドは使わないで、できるはずなのですが・・・。) コピーができずに困ってます、よろしくお願いします。 Const IMAX As Long = 10 Const JMAX As Long = 10 Sub A() Cells.Clear Dim A(IMAX + 1, JMAX + 1) As Long Dim B(IMAX + 1, JMAX + 1) As Long For i = 1 To IMAX + 1 For j = 1 To JMAX Cells(i, j) = j A(i, 1) = A(i, JMAX + 1) '左端の配列を一番右にコピーする A(i, JMAX + 2) = A(i, 2) '左から2番目の配列を右から2番目にコピーする Next Next End Sub

  • 塗る部分と塗らない部分を条件によってわけたいのですが・・・

    今回困っているのは下のマクロで (1)紺なら足跡を残し、青なら進んでいるセルだけ青にして前回の青の足跡は残さないで (2)セルが紺の足跡でいっぱいになるまで、これを続けます。 この条件をここに追加しようと思ったのですが、なかなかうまく行きません。ヒントだけでも、何か名案がありましたらご回答お願いします。 Const IMAX As Long = 30 '最大 i 座標 Const JMAX As Long = 20 '最大 j 座標 Const NMAX As Long = 50 '最大ステップ数 Const motigomi As Long = 5 'ゴミ「○歩につき●個捨てる」数 Dim ip(MMAX) As Long '人の i 座標 Dim jp(MMAX) As Long '人の j 座標 Dim occ(IMAX, JMAX) As Long Dim pre(IMAX, JMAX) As Integer Dim post(IMAX, JMAX) As Integer Sub ashiato() Randomize Cells.Clear For n = 1 To NMAX 'ステップを進める For m = 1 To 1   iprev = ip(m) '元いた位置 jprev = jp(m) '移動先 (i, j) を決める i = i - 1 '周期境界条件 If i > IMAX Then i = i - IMAX If i < 1 Then i = i + IMAX If j > JMAX Then j = j - JMAX If j < 1 Then j = j + JMAX '実際に移動 ip(m) = i jp(m) = j '色付けを更新 pre(i, j) = Int(motigomi * Rnd()) If pre(i, j) = 1 Then Cells(i, j).Interior.color = RGB(10, 50, 100) Else Cells(iprev, jprev).Clear Cells(i, j).Interior.color = RGB(40, 50, 400) End If Next Next End Sub

  • CSVファイルの読み込み

    以下のようなCSVファイルを読み込みたいと思っています。 0.575092,0.030525 0.565324,0.018315 0.555556,0.013431 0.553114,0.013431 0.54823,0.015873 0.538462,0.013431 0.531136,0.006105 0.52381,-0.003663 0.516484,-0.010989 0.501832,-0.015873 0.489622,-0.018315 0.477412,-0.020757 0.46276,-0.020757 ・ ・ ・ 50000*2のデータで、以下のようなプログラムを使用しました。 #include <stdio.h> #include <stdlib.h> #include <string.h> /* 確保するデータ保存領域の大きさ(N行×M列) */ #define N 50000 #define M 2 /* データの区切り文字 */ #define SEP_DATA ',' int csv_read(char filename[], double csv[N][M]) { /* ファイルオープン */ FILE *fp; if( (fp = fopen(filename, "r")) == NULL ) { printf(" file open error!!\n"); return -1; } /* 1行毎に読み出し */ char line[256], *ptr; int i, j, k; i=0; while (fgets(line, 256, fp) != NULL) { printf("*%s", line); ptr = line; j=0; do{ /* line[j]から次のタブ文字までを数値に変換 */ csv[i][j] = atof(ptr); /* 次のタブ文字の位置を探す */ ptr = strchr(ptr, SEP_DATA); /* タブ文字の次の文字を示す */ if (ptr!=NULL) { ptr++; } j++; }while(ptr!=NULL && j<M); i++; } /* ファイルクローズ */ fclose(fp); return 0; } int main(int argv, char *argc[]) { char filename[256]; if( argv > 1){ strcpy(filename, argc[1]); } else { printf("Please Input Filename:"); scanf("%s", filename); } /* データ保存用の領域を確保 */ double (*csvdata)[M]; csvdata = (double(*)[M])malloc(sizeof(csvdata) * N); if ( csvdata == NULL ){ return -1; } int i,j; /* 配列の初期化 */ for( i=0; i<N; i++) { for( j=0; j<M; j++) { csvdata[i][j] = 0.0; } } /* CSVデータの読み込み */ if( csv_read(filename, csvdata) < 0 ) { return -1; } /* 配列の出力 */ for( i=0; i<N; i++) { printf("%lf", csvdata[i][0]); for( j=1; j<M; j++) { printf("\t%lf", csvdata[i][j]); } printf("\n"); } free(csvdata); csvdata = NULL; return 0; } しかし、コンパイルは通るのですが実行時にエラーが出てしまいます。 データの大きさに問題があると思うのですが、原因がわかりません。おかしな所のご指摘を頂きたいです。よろしくお願いします。

  • LU分解について

    こんにちは。 行列のLU分解のcによるプログラムを勉強している者です。 LU分解のcによるプログラムについてお尋ねしたいことがございます。 ニューメリカルレシピに、LU分解の方法として 以下のようなコードが記載せれておりました。 void ludcmp(double **a, int n, int *indx, double *d) { int i,imax,j,k; double big,dum,sum,temp; double *vv; // 各行の暗黙のスケーリングを記録する. vv=vector(n); *d=1.0; // まだ行交換していない. for (i=0;i<n;i++) { // 行についてループし,暗黙のスケーリングの情報を得る. big=0.0; for (j=0;j<n;j++) if ((temp=fabs(a[i][j])) > big) big=temp; if (big == 0.0) printf("Singular matrix in routine ludcmp\n"); // 最大要素が0なら特異行列である. vv[i]=1.0/big; // スケーリングを記録する. } for (j=0;j<n;j++) { // Crout法,列についてのループ for (i=0;i<j;i++) { // 方程式(2.3.12)のi=j以外 sum=a[i][j]; for (k=0;k<i;k++) sum -= a[i][k]*a[k][j]; a[i][j]=sum; } big=0.0; for (i=j;i<n;i++) { sum=a[i][j]; for (k=0;k<j;k++) sum -= a[i][k]*a[k][j]; a[i][j]=sum; if ( (dum=vv[i]*fabs(sum)) >= big) { big=dum; imax=i; } } if (j != imax) { for (k=0;k<n;k++) { dum=a[imax][k]; a[imax][k]=a[j][k]; a[j][k]=dum; } *d = -(*d); vv[imax]=vv[j]; } indx[j]=imax; if (a[j][j] == 0.0) a[j][j]=TINY; if (j != n) { dum=1.0/(a[j][j]); for (i=j+1;i<n;i++) a[i][j] *= dum; } } free_vector(vv); } 例えば、LU分解させたい行列3×3の({4,7,6}{2,5,9}{3,1,8})だとしたら、 メイン関数にどのように書いたらLU分解を実行できるでしょうか? ニューメリカルレシピを買って読んでみたものの、よく理解できず、質問させていただきます。 稚拙な質問かもしれませんが、どうぞよろしくお願いいたします。

  • 偏微分のプログラムについてです.

    (∂^2 u)/(∂x^2 )+(∂^2 u)/(∂y^2 )=2(x^2+y^2 ) 境界上でu(0,y)=u(x,0)=0,u(1,y)=y^2,u(x,1)=x^2である.点(0.5,0.5)の値を求めよ.その際きざみ幅を幾つか変化させることで,反復回数がどのように変化するか確かめよ. という問題です.自分で以下のプログラムを作ったのですが,コンパイルされません.ぜひどこがおかしいか教えてください. #include<stdio.h> #define EPS 10e-6 #define N 100 #define M 100 main(void){ int i,j; int n=19,m=19,r=0; double h,x0,S; double u1[N][M],u2[N][M]; h=2.0/(n+1); for(i=0;i<n+2;i++){ for(j=0;j<m+2;j++){ u1[i][j]=0.0; } } do{ for(i=0;i<n+2;i++){ u2[i][0]=0.0; u2[i][m+1]=0.0; } for(j=0;j<m+2;j++){ u2[0][j]=0.0; u2[n+1][j]=0.0; } for(i=1;i<n+1;i++){ for(j=1;j<m+1;j++){ u2[i][j]=(u1[i-1][j]+u1[i][j+1]+u1[i+1][j]+u1[i][j-1]+2.0*h*h)/4.0; } } r++; S=fabs(u1[(n+1)/2][(m+1)/2]-u2[(m+1)/2][(m+1)/2]); for(i=0;i<n+2;i++){ for(j=1;j<m+1;j++){ u1[i][j]=u2[i][j]; } } } while(S>EPS); x0=u2[(n+2)/2][(m+2)/2]; printf("きざみ幅=%lf\n",h); printf("反復回数=%d\n",r); printf("点(0.5,0.5)=%lf\n",x0); }

専門家に質問してみよう