【问题标题】:Reading Text File into C Correct Order将文本文件读入 C 正确顺序
【发布时间】:2016-07-29 07:29:01
【问题描述】:

我正在编写代码来读取文件并将数字存储在数组中。代码本身正在工作,但数字没有正确存储在数组中,因此,我没有得到所需的输出。这是我的代码:

/* 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 行之后的数字(第三块中的四个:1、1.5、2.5、1.5)应该位于箭头的另一侧。

【问题讨论】:

  • sizeof 调用中的sizeof 参数应该做什么?它们是多余的。
  • 我认为您有嵌套错误。您应该首先使用嵌套循环读取所有a[j][i],然后在单独的循环中读取所有b[i]。您在阅读 a[j][i] 的同一个 lop 中阅读了 b[i],但输入文件似乎没有这样组织。 (除非是误解了输入格式。)
  • @MOehm 我认为它们可能会帮助定义每行的大小,以便代码知道何时中断。另外,您是否建议为 b[i] 使用完全独立的 for 循环?
  • 打开警告,您将了解到不需要sizeof 参数。 Plain fscanf 是一个比较粗糙的扫描功能;要扫描的数据大小必须通过大小修饰符给出,在您的情况下,%lf 中的 l
  • 是的,我建议一个单独的循环。流是按行排列的,从左到右。您的代码必须以相同的方式读取数据。我还建议将打印与扫描分开并扫描所有内容,包括前面的x

标签: c arrays file scanf


【解决方案1】:

您读取数据的方式与您的输入文件不匹配。该文件看起来像

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");

【讨论】:

    【解决方案2】:

    我很抱歉写这个作为答案,而不是评论(还没有声誉),但我认为当你

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

    指向二维数组的指针可能有问题。 (我也会尝试在这里省略 sizeof()。)

    这篇文章讨论了指向二维数组的指针:

    Create a pointer to two-dimensional array

    一切顺利!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-28
      • 1970-01-01
      • 2021-09-25
      • 1970-01-01
      • 2011-01-03
      相关资源
      最近更新 更多