感谢我之前得到的所有帮助。
在下面的程序中,我想创建一个随机矩阵,将其打印到屏幕上,将其写入文件,然后从文件中扫描该矩阵的副本并将副本打印到屏幕上,除了我试着从文件中读取,我的代码中的算法是不正确的,我想,
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 :(得分: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
传递给函数,代码可以指示它读取到调用代码的矩阵的大小。