2016-04-08 12 views
2

ファイルを読み込んで数値を配列に格納するコードを作成しています。コード自体は機能していますが、数値は配列に適切に格納されていないため、希望の出力が得られません。私のコードは次のとおりです。Cでのテキストファイルの読み取り正しい順序

/* code to solve a nxn system using the Gauss-Seidel method */ 
#include <stdio.h> 
#include <math.h> 
#include <stdlib.h> 
#include <malloc.h> 

#define MAX_DIM 100 
#define MAX_ITER 500 
#define TOLERANCE 1.e-6 
void gauss_seidel(double **a, double b[], double x[], int n); 
void main() 
{ 
    int i, j, n; 
    int violation_counter, answer; 
    double sum; 
    /* read in data */ 
    n = MAX_DIM + 1; 
    FILE *inf, *onf; 
    char fileName[256]; 
    printf("Enter file Name: "); 
    scanf("%s", fileName); 
    inf = fopen(fileName, "r"); 
    if(inf != NULL){ 
     while (n > MAX_DIM) { 
      fscanf(inf, "%d", &n); 
     } 
     int *violation_rows = (int *)malloc(sizeof(int) * n); 
     double **a = (double **)malloc(sizeof(double *) * n); 
     double *b = (double *)malloc(sizeof(double) * n); 
     double *x = (double *)malloc(sizeof(double) * n); 
     for(i = 0; i < n; ++i){ 
      a[i] = (double *)malloc(sizeof(double) * n); 
     } 
     for (i = 0; i < n; i++) { 
      for (j = 0; j < n; j++) { 
       fscanf(inf, "%lf", &a[i][j], sizeof(a[i][j])); 
       printf("%.2lf ", a[i][j]); 
      } 
      fscanf(inf, "%lf", &b[i], sizeof(b[i])); 
      printf("-> %.2lf\n", b[i]); 
     } 
     printf("\n"); 
     /* test the convergence criterion */ 
     violation_counter = 0; 
     for (i = 0; i < n; i++) { 
      sum = 0.0; 
      for (j = 0; j < n; j++) 
       if (i != j) 
        sum = sum + fabs(a[i][j]); 
      if (fabs(a[i][i]) < sum) { 
       violation_rows[violation_counter] = i; 
       violation_counter = violation_counter + 1; 
      } 
      if (a[i][i] == 0.0) { 
       printf("Found diagonal element equal to zero; rearrange equations; exiting ...\n"); 
       exit(0); 
      } 
     } 

     if (violation_counter > 0) { 
      printf("The Gauss-Seidel convergence criterion is violated in %d rows out of %d\n", violation_counter, n); 
      printf("Specifically, it was violated in rows:\n"); 
      for (i = 0; i < violation_counter; i++) 
       printf("%d ", violation_rows[i]); 

      printf("\n"); 

      printf("Enter 1 if you want to continue; any other number to abort : "); 
      scanf("%d", &answer); 

      if (answer != 1) 
       exit(1); 
      printf("Check results carefully\n\n"); 
     } 
     /* initialize the solution vector -- initial guesses */ 
     for (i = 0; i < n; i++) { 
      fscanf(inf, "%lf", &x[i], sizeof(x[i])); 
      printf("x[%d] = %.2lf\n", i, x[i]); 
     } 

     fclose(inf); 
     /* solve the system */ 
     gauss_seidel(a, b, x, n); 
     /* output solution */ 

     printf("Enter file Name: "); 
     scanf("%s", fileName); 
     onf = fopen(fileName, "w"); 
     for (i = 0; i < n; i++) 
      fprintf(onf, "x[%d]=%f\n", i, x[i]); 
     fprintf(onf, "\n"); 
     fclose(onf); 
    } 
    else{ 
     printf("Can not open %s to read\n", fileName); 
    } 
    return; 
} 

コードの出力に数字が正しく格納されていません。

4 

2 -1 0 0 
-1 3 -2 0 
0 -2 5 -3 
0 0 -3 3 

1 
1.5 
2.5 
1.5 

0 
0 
0 
0 

そして、私は取得していた結果は

2 -1 0 0 -> -1 
3 -2 0 0 -> -2 
5 -3 0 0 -> -3 
3 1 1.5 2.5 -> 1.5 

としてだけでなく、斜めの収束誤差である:例えば、次のように、私のテキストファイルです。何が原因でファイルが正しく保存されないのですか?

編集:4x4の行(3番目のブロックの4:1,1.5,1.5,1.5)の後の数字は、矢印の反対側にあると想定されます。

+1

'fscanf'呼び出しの' sizeof'パラメータはどうしたらいいですか?彼らは超過です。 –

+1

あなたはネスティングエラーがあると思います。あなたはすべての 'a [j] [i]'を入れ子にしたループで最初に読んで、すべての 'b [i]'を別々のループで読むべきです。あなたは 'a [j] [i]'を読む同じlopで 'b [i]'を読むが、入力ファイルはそれほど整理されていないようだ。 (入力形式を間違って解釈しない限り) –

+0

@MOehm私は、各行のサイズを定義するのに役立つと思っていたので、コードがいつ壊れるかを知ることができました。また、 'b [i]'の 'for'ループを完全に分離することを提案していますか? –

答えて

2

データの読み方が入力ファイルと一致しません。ファイルは

n 

a11 a12 a13 
a21 a22 a23 
a31 a32 a33 

b1 
b2 
b3 

のように見えるが、それは

n 

a11 a12 a13 b1 
a21 a22 a23 b2 
a31 a32 a33 b3 

だから、あなたは別のベクトルでbベクトルを読むべきであるかのように、あなたはそれを読みます。

// Scan first ... 
    for (i = 0; i < n; i++) { 
     for (j = 0; j < n; j++) { 
      fscanf(inf, "%lf", &a[i][j]); 
     } 
    } 

    for (i = 0; i < n; i++) { 
     fscanf(inf, "%lf", &b[i]);   
    } 

    for (i = 0; i < n; i++) { 
     fscanf(inf, "%lf", &x[i]); 
    } 

    // ... then print 
    for (i = 0; i < n; i++) { 
     for (j = 0; j < n; j++) { 
      printf("%.2lf ", a[i][j]); 
     } 
     printf("-> %.2lf\n", b[i]); 
    } 
    printf("\n"); 

    for (i = 0; i < n; i++) { 
     printf("x[%d] = %.2lf\n", i, x[i]); 
    } 
    printf("\n"); 
0

私は答え、ないコメント(まだ評判を持っていない)としてこれを書くのは申し訳ないが、私はときに

fscanf(inf, "%lf", &a[i][j], sizeof(a[i][j])); 

ことへのポインタに何か問題があるかもしれないと思います2次元配列(また、私はここに)(はsizeofを省略しようとするだろう。)

2次元配列へのポインタについてのこの記事会談:

Create a pointer to two-dimensional array

すべてのベストを!

関連する問題