C将随机矩阵写入文件,然后使用格式化I / O从文件读取和复制所述矩阵

时间:2011-12-28 17:53:02

标签: c file matrix scanf

感谢我之前得到的所有帮助。

在下面的程序中,我想创建一个随机矩阵,将其打印到屏幕上,将其写入文件,然后从文件中扫描该矩阵的副本并将副本打印到屏幕上,除了我试着从文件中读取,我的代码中的算法是不正确的,我想,

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 ;   
}

2 个答案:

答案 0 :(得分:3)

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

虽然您的整个代码太长而无法阅读,但这部分绝对是错误的。您必须在某个时间递增指针,否则只会初始化第一个元素。尝试:

*ptr++ = x;

valgrind是检测此类错误的绝佳工具,当您访问(或打印)未初始化的内存时,它会引发错误。

答案 1 :(得分:2)

问题在于,内存管理经常出现问题。但是代码中还有很多其他的奇怪之处:<​​/ p>

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传递给函数,代码可以指示它读取到调用代码的矩阵的大小。