2016-04-08 21 views
2

Bir dosyada okumak ve sayıları bir dizide saklamak için bir kod üzerinde çalışıyorum. Kodun kendisi çalışıyor, ancak numaralar dizide doğru şekilde saklanmıyor ve bu şekilde istenen çıktıyı alamıyorum. İşte benim kodum: Metin Dosyasını C Doğru Siparişe Okuma

/* 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; 
} 
Kodun çıktısı, numaraları doğru şekilde saklamıyor.

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 

Ve alıyorum sonuç

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

yanı sıra bir diyagonal yakınsama hatadır: Örneğin, benim metin dosyası aşağıdaki gibidir. Dosyanın düzgün şekilde kaydedilmemesine neden olan nedir?

DÜZENLEME: 4x4 satırından sonraki sayılar (üçüncü blokta dörde: 1, 1,5, 2,5, 1.5) okun diğer tarafında olmalıdır.

+1

"fscanf" işlevlerindeki "sizeof" parametreleri ne yapmalı? Onlar süper. –

+1

Sanırım bir yuvalama hatası var. Hepsi bir [j] [i] 'yi ilk önce yuvalanmış bir döngü ile okumalı ve daha sonra ayrı bir döngüde' b [i] 'yi okumalısınız. “A [j] [i]' yi okuduğunuz yerdeki aynı lopta okuyorsunuz, ama giriş dosyası bu şekilde organize edilmiş gibi görünmüyor. (Giriş formatını yanlış yorumlamadıkça). –

+0

@MOehm Kodun ne zaman kırılacağını bilmesi için her satırın boyutunu belirlemelerine yardımcı olabileceklerini düşündüm. Ayrıca, “b [i]' için tamamen ayrı bir 'for' döngüsü öneriyor musunuz? –

cevap

2

Verilerdeki okuma şekli, giriş dosyanızla eşleşmiyor. Dosya

n 

a11 a12 a13 
a21 a22 a23 
a31 a32 a33 

b1 
b2 
b3 

benziyor ama bunu

n 

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

sanki Yani ayrı bir vektör içinde b vektörü okumalısınız oku. Ayrıca her şeyi okuduktan ve her şeyi okuduktan sonra ayrı ayrı yazdırmayı öneririm:

// 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

bir cevap değil, bir yorum (Henüz itibar yoktur) olarak bunu yazmak için üzgünüm, ama bence sen

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

işaretçisi ile yanlış bir şey olabilir ne zaman iki boyutlu dizi. (Aynı zamanda burada) (sizeof atlayarak çalışacaktı.) Önerilerle ilgili

Bu mesaj görüşmelerini iki boyutlu dizilere:

Create a pointer to two-dimensional array

tüm iyi!