2011-12-28 47 views
3

感謝您收到我之前獲得的所有幫助。C將隨機矩陣寫入文件,然後使用格式化的I/O從文件讀取和複製所述矩陣

在下面的程序中,我想創建一個隨機矩陣,將其打印到屏幕上,將其寫入文件,然後從文件中掃描該矩陣的副本並將副本打印到屏幕上,除了當我嘗試從文件中讀取,在我的代碼的算法是不正確,我認爲,

的scanf函數失敗,我不知道爲什麼....

double *matrix_read(FILE *fptr, double *mat, int m, int n) ; 

double *matrix_read(FILE *fptr,double *mat, int m, int n) { 
    int i,j; 
    double *ptr,x ; 
    ptr=mat; 

    if((fptr=fopen("matrixA.txt","r"))==NULL) 
    { 
     puts("Cannot Open File"); 
    } 
    rewind(fptr); 
    fscanf(fptr,"\n\nrows %d, columns %d\n\n", &m, &n) ; 
    mat = (double *) malloc(sizeof(double) * m * n) ; 

    for (i=0; i < m; i++) 
    { 
     for (j=0; j < n; j++) 
     { 
      fscanf(fptr, " %5.2lf", &x); 
      *ptr++=x; 
     } 
    } 
    fclose(fptr); 

    return mat ; 
} 

在我main,該功能如下所示:

rand_matrix(MATRIX.matrix, MATRIX.rows, MATRIX.cols); /* populates matrix with random      data */ 

print_matrix(MATRIX.matrix, MATRIX.rows, MATRIX.cols) ; /* prints the matrix */ 

matrix_write(fptr, MATRIX.matrix, MATRIX.rows, MATRIX.cols) ; /* writes matrix to  file*/ 

_flushall(); 
getchar(); 

MATRIX1.matrix=matrix_read(fptr, MATRIX.matrix, MATRIX.rows, MATRIX.cols) ; /* reads  above matrix from file as a copy */ 

print_matrix(MATRIX1.matrix, MATRIX.rows, MATRIX.cols) ; /* prints this copyed matrix*/ 

當打印被複制的矩陣我得到一堆亂碼,海量數字(即1259000000000000000000)我認爲這些都是內存位置名稱或東西,有人可以幫我修理我的read_matrix()函數?

非常感謝。

下面是我的完整代碼(它編譯)。

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <malloc.h> 
#include <conio.h> 

double random() ; 
double *rand_matrix(double *mat, int m, int n) ; 
void print_matrix(double *mat, int m, int n) ;  
void matrix_write(FILE *fptr, double *mat, int m, int n) ;  
double *matrix_read(FILE *fptr, double *mat, int m, int n) ;  

int main() 
{ 

    struct matrep { 
     unsigned rows,cols; 
     double *matrix; 
    } MATRIX,MATRIX1,MATRIX2; 

    int check = 0 ; 
    FILE *fptr; 

    printf("\n\nMatrix Manipulations Program"); 

    do { 
     printf("\n\nEnter matrix dimensions : rows x columns : "); 
     check = scanf("%d x %d", &MATRIX.rows, &MATRIX.cols); 
     _flushall(); 
    } while (check != 2 || MATRIX.rows < 1 || MATRIX.cols < 1) ; 

    MATRIX.matrix = (double *) malloc(sizeof(double) * MATRIX.rows * MATRIX.cols) ; 

    if (!MATRIX.matrix){ 
     printf("\n\nSTOP : unable to allocate memory - exiting program") ; 
     exit(1) ; 
    } 

    rand_matrix(MATRIX.matrix, MATRIX.rows, MATRIX.cols); /* populates matrix with random data */ 

    print_matrix(MATRIX.matrix, MATRIX.rows, MATRIX.cols) ; /* prints the matrix */ 

    matrix_write(fptr, MATRIX.matrix, MATRIX.rows, MATRIX.cols) ; /* writes matrix to  file*/ 

    _flushall(); 
    getchar(); 

    MATRIX1.matrix=matrix_read(fptr, MATRIX.matrix, MATRIX.rows, MATRIX.cols) ; /* reads  above matrix from file as a copy */ 

    print_matrix(MATRIX1.matrix, MATRIX.rows, MATRIX.cols) ; /* prints this copyed matrix*/ 

    _flushall(); 
    getchar(); 
} 

/***********************************************************/ 

double random() 
{ 
    static int seeded = 0; 
    double val ; 

    if (!seeded) 
    { 
     srand(time(NULL)) ; 
     seeded = 1; 
    } 

    val = ((double)rand())/ (double)RAND_MAX * 100.0 ; 

    return val ; 
} 

/***********************************************************/ 

double *rand_matrix(double *mat, int m, int n) 
{ 
    double *ptr ; 
    int i, j ; 

    ptr = mat ; 

    for (i=0; i < m; i++){ 
     for (j=0; j < n; j++){ 
      *ptr++ = random() ; 
     } 
    } 
    return mat ; 
} 

/***********************************************************/ 

void print_matrix(double *mat, int m, int n) 
{ 
    double *ptr ; 
    int i, j ; 

    if (mat==0 || m==0 || n==0) 
    { 
     printf("\n\nEmpty matrix"); 
     return ;  
    } 

    ptr = mat ; 

    printf("\n\nrows %d, columns %d\n\n", m, n) ; 

    for (i=0; i < m; i++) 
    { 
     for (j=0; j < n; j++) 
     { 
      printf("\t%5.2lf", *ptr++); 
     } 
     printf("\n") ; 
    } 

} 

/***********************************************************/ 
void matrix_write(FILE *fptr,double *mat, int m, int n) { 
    int i,j; 
    if((fptr=fopen("matrixA.txt","w"))==NULL) 
    { 
     puts("Cannot Open File"); 
    } 
    fprintf(fptr,"\n\nrows %d, columns %d\n\n", m, n) ; 

    for (i=0; i < m; i++) 
    { 
     for (j=0; j < n; j++) 
     { 
      fprintf(fptr, " %5.2lf", *mat++); 
     } 
     fprintf(fptr, "\n") ; 
    } 
    fclose(fptr);  
} 

/***********************************************************/ 
double *matrix_read(FILE *fptr,double *mat, int m, int n) { 
    int i,j; 
    double *ptr,x ; 
    ptr=mat; 

    if((fptr=fopen("matrixA.txt","r"))==NULL) 
    { 
     puts("Cannot Open File"); 
    } 
    rewind(fptr); 
    fscanf(fptr,"\n\nrows %d, columns %d\n\n", &m, &n) ; 
    mat = (double *) malloc(sizeof(double) * m * n) ; 

    for (i=0; i < m; i++) 
    { 
     for (j=0; j < n; j++) 
     { 
      fscanf(fptr, " %5.2lf", &x); 
      *pt++r=x; 
     } 
    } 
    fclose(fptr); 

    return mat ; 
} 
+0

'* pt ++ r = x;'in'matrix_read()'? – 2011-12-28 18:05:45

+0

注意:在程序結束時,你必須free()''malloc()''ed內存! – 2011-12-28 18:09:34

回答

2

問題就像在內存管理中經常發生的那樣。但代碼中還有很多其他的怪異特徵:

double *matrix_read(FILE *fptr, double *mat, int m, int n) 
{ 
    int i, j; 
    double *ptr, x; 
    ptr = mat; // This points to the matrix passed into the function 

    // Why pass fptr as an argument if the first thing you do is open a file? 
    // Especially since you close it at the end 
    if ((fptr = fopen("matrixA.txt", "r")) == NULL) 
    { 
     puts("Cannot Open File"); 
     return 0; // Get out; do not use the file stream! 
    } 
    rewind(fptr); // This is unnecessary; a file is opened for reading at the start 
    if (fscanf(fptr, "\n\nrows %d, columns %d\n\n", &m, &n) != 2) 
    { 
     puts("Failed to read dimensions of array"); 
     return 0; 
    } 
    mat = (double *)malloc(sizeof(double) * m * n); 
    // Now you've got a new matrix, but you did not reinitialize ptr to use it! 

圍繞運算符還有一些適度的隨機間距。一致性至關重要;因爲,在逗號之後的空格而不是之前;分號後的空格而不是之前;二元運算符周圍的空格

此外,你有一個矩陣的結構,但你不會將該結構傳遞給你的函數。如果你使用它,你的代碼可能會更好。 OTOH,您必須將struct matrep的定義移到main()之外,以便可以通過函數查看。

int matrix_read(struct matrep *mat) 
{ 
    FILE *fptr; 
    unsigned m, n; 

    if ((fptr = fopen("matrixA.txt", "r")) == NULL) 
    { 
     fprintf(stderr, "Cannot Open File %s\n", "matrixA.txt"); 
     return -1; 
    } 
    if (fscanf(fptr, "\n\nnrows %u, columns %u\n\n", &m, &n) != 2) 
    { 
     fprintf(stderr, "Failed to read dimensions\n"); 
     return -1; 
    } 
    // ?? free(mat.matrix); ?? /* to release previously allocated memory */ 
    mat.matrix = (double *)malloc(sizeof(double) * m * n); 
    if (mat.matrix == 0) 
    { 
     fprintf(stderr, "Failed to allocate %d*%d matrix\n", m, n); 
     return -1; 
    } 
    double *ptr = mat.matrix; 

    for (int i = 0; i < m; i++) 
    { 
     for (int j = 0; j < n; j++) 
     { 
      double x; 
      if (fscanf(fptr, " %5.2lf", &x) != 1) 
      { 
       fprintf(stderr, "Failed to read element matrix[%d,%d]\n", i, j); 
       free(mat.matrix); 
       mat.matrix = 0; 
       mat.columns = 0; 
       mat.rows = 0; 
       return -1; 
      } 
      *ptr++ = x; 
     } 
    } 
    fclose(fptr); 
    mat.columns = m; 
    mat.rows = n; 

    return 0; // Success 
} 

也有很多變化,但最顯著的是,通過將struct matrep到函數,代碼可以表明它讀給調用代碼矩陣的大小。

3
for (i=0; i < m; i++) 
{ 
    for (j=0; j < n; j++) 
    { 
     fscanf(fptr, " %5.2lf", &x); 
     *ptr=x; 
    } 
} 

當你的整個代碼太長閱讀,這部分肯定是不對的。您必須在某個時間遞增指針,否則只有第一個元素會被初始化。嘗試:

*ptr++ = x; 

valgrind是檢測這樣的錯誤一個偉大的工具,它會拋出當你訪問一個錯誤(或打印,你的情況)未初始化的內存。

+0

我已經修復了這個錯誤,但是代碼仍然拋出相同或者非常相似的未初始化的內存 – 2011-12-28 18:01:36