代码无法正确读取输入文件

时间:2016-04-07 22:36:08

标签: c matrix

我的代码似乎无法正确读取输入文件。它以某种方式只读取我的矩阵的第一行,然后在"右侧"下输入第二行。而不是在"系数矩阵"下为矩阵创建另一条线。此外,它打印第三行"初步猜测"而不是矩阵的第三行。

我假设错误位于我在下面发布的代码中,但如果您认为下面的代码是正确的,并且我的代码中的其他位置是此问题源自的地方,请告诉我。

#include <stdio.h>
#include <math.h>
#include <stdlib.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 print_screen_A_b_x(double **a, double *b, double *x, int n);
void main()

{
    int i, j, *ptr, n;
    int violation_counter, answer;
    int violation_rows[MAX_DIM];
    double sum;
    double **a;
    double *b, *x;
    FILE *input_Ptr;    //pointer to input file

                    //Open the input file
    input_Ptr = fopen ( "my_input.txt", "r" );
        if (input_Ptr == NULL) {
        puts("\nInput file was not opened succesfully.\n");
        exit(-1);
}

//read size of the problem
fscanf(input_Ptr, "%d", &n);


//dynamic memory allocation

a = (double **) malloc (n * sizeof(double *));
for (i = 0; i < n; i++) {
    a[i] = (double *) malloc (n * sizeof(double));
}
b = (double *) malloc (n * sizeof(double));
x = (double *) malloc (n * sizeof(double));

/* read in data */
//n = MAX_DIM + 1;
//while (n > MAX_DIM) {
    //fscanf(input_Ptr, "%d", &n);
//}

printf("\n");
for (i = 0; i < n; i++) {
    for (j = 0; j < n; j++) {
        fscanf(input_Ptr, "%lf", &a[i][j]);
    }
    for (i = 0; i < n; i++) {
        fscanf(input_Ptr, "%lf", &b[i]);
    }
    for (i = 0; i < n; i++) {
        fscanf(input_Ptr, "%lf", &x[i]);
    }

    printf("\n");
}

fclose(input_Ptr);

print_screen_A_b_x(a, b, x, n);

puts("Solution vector:");
for (i = 0; i < n; i++) {
    printf("x[%d] = %10.5f \n", i, x[i]);

    //free memory
    for (i = 0; i < n; i++) {
        free(a[i]);
    }
    free(a);
    free(b);
    free(x);

    return 0;
}
/* 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++) {
    printf("Enter an initial guess for x[%d] of the solution vector : ", i);
    scanf("%lf", &x[i]);
}
/* solve the system */
gauss_seidel(a, b, x, n);
/* output solution */
for (i = 0; i < n; i++)
    printf("x[%d]=%f\n", i, x[i]);
printf("\n");
}

/* function to solve a system using Gauss-Seidel */
void gauss_seidel(double **a, double *b, double *x, int n)

{
double maxerror = 1.0e-7;
double iteration_error;
double e, sum, temp;
int i, j;

while (maxerror > 1.e-6) {
    iteration_error = 0.0;

    for (i = 0; i < n; i++) {
        sum = 0.0;
        for (j = 0; j < n; j++) {
            if (i != j)
                sum = sum + (a[i][j] * x[j]);
        }
    }

    temp = (a[i][n] - sum) / a[i][i];
    e = fabs((temp - x[i]) / x[i]);
    x[i] = temp;

    if (e > iteration_error)
        iteration_error = e;
}
maxerror = iteration_error;
}

void print_screen_A_b_x(double **a, double *b, double *x, int n)
{
int i, j;

printf("\n Coefficient matrix:\n");
for (i = 0; i < n; i++) {
    for (j = 0; j < n; j++) {
        printf("%10.2f", a[i][j]);
    }
    printf("\n");
}

printf("\n Right hand side vector:\n");
for (i = 0; i < n; i++) {
    printf("%10.2f \n", b[i]);
}

printf("\n Initial guess:\n");
for (i = 0; i < n; i++) {
    printf("%10.5f \n", x[i]);
}

return;
}

2 个答案:

答案 0 :(得分:0)

在帖子循环\r\n语句中添加if

答案 1 :(得分:0)

你告诉我们:

void gauss_seidel(double a[][MAX_DIM], double b[], double x[], int n)

void print_screen_A_b_x(double **a, double *b, double *x, int n)

您不能将与第一个参数相同的对象传递给两个函数;它们(根本上)是不同的类型,即使你同时使用双下标。由于您尚未显示矩阵的实际定义方式,因此我们无法为您提供更多帮助。

你的编译器应该尖叫一下(或两个)调用。注意你的编译器。它比你现在更了解C。除非出现严重问题,否则不会反对。如果你的编译器没有抱怨,那么你需要打开编译警告(并使用C11,或者使用C99,作为标准的版本 - 绝对不是C90)或者获得更好的编译器。

分析一次更新

问题中的一个更新代码版本的输入代码如下:

// read size of the problem
fscanf(input_Ptr, "%d", &n);

// dynamic memory allocation
a = (double **)malloc(n * sizeof(double *));
for (i = 0; i < n; i++)
{
    a[i] = (double *)malloc(n * sizeof(double));
}
b = (double *)malloc(n * sizeof(double));
x = (double *)malloc(n * sizeof(double));

printf("\n");
for (i = 0; i < n; i++)
{
    for (j = 0; j < n; j++)
    {
        fscanf(input_Ptr, "%lf", &a[i][j]);
    }
    for (i = 0; i < n; i++)
    {
        fscanf(input_Ptr, "%lf", &b[i]);
    }
    for (i = 0; i < n; i++)
    {
        fscanf(input_Ptr, "%lf", &x[i]);
    }

    printf("\n");
}

好消息是,除了没有错误检查外,内存分配看起来还不错。

坏消息是,在数据看起来最合理的推论下,主要的输入循环是完全错误的。假设n中的值为N,则输入循环的第一次迭代将N值读入a[0](这很好),然后将N值读入b(这很好)尽管如此),然后将N值读入x(就其而言也是如此)。 i的值现为n;当它被外循环递增时,i大于n,所以外循环终止,但你只读取主矩阵的一行。

最有可能的是,您应该使用:

// read size of the problem
if (fscanf(input_Ptr, "%d", &n) != 1)
    …report error and skedaddle…
// Check n for plausibility
if (n < 1 || n > 1000)
    …report implausibility and skedaddle…

// dynamic memory allocation
…as before, except you should error check all the allocations…

printf("\n");
for (i = 0; i < n; i++)
{
    for (j = 0; j < n; j++)
    {
        if (fscanf(input_Ptr, "%lf", &a[i][j]) != 1)
            …report error and skedaddle…
    }
}

for (i = 0; i < n; i++)
{
    if (fscanf(input_Ptr, "%lf", &b[i]) != 1)
        …report error and skedaddle…
}

for (i = 0; i < n; i++)
{
    if (fscanf(input_Ptr, "%lf", &x[i]) != 1)
        …report error and skedaddle…
}

您不检查错误的事实意味着您不知道什么时候出错。你不能不知道什么时候出错了,所以你不能不检查错误。

skedaddle |skɪdad(ə)l | 动词[no obj。非正式的 - 快速或匆忙离开;逃跑。