我正在制作一个程序,我必须不断地在函数中使用矩阵,这是众多函数中的一个,这个函数应该打开一个外部文件,这是一个数据集,其中数据是用表格,它打开文件并将数据保存在矩阵M中,我知道这个矩阵由6列组成,但行号是未知的,我知道错误是我声明矩阵的地方,它必须用指针声明因为函数返回矩阵。
//type float** since it will return a matrix
float **carga_archivo(char *nombre_archivo)
{
float **M=(float **)malloc(6*sizeof(float*)); //error should be here
int i=0;
FILE *archivo; //FILE type pointer to open the external file
archivo=fopen(nombre__archivo,"r"); //Opens the file in the address indicated
//"nombre_de_archivo" is a variable
while(!feof(archivo)) //Browses the file row per row till the end of it
{
//saves the data in its corresponding place in the matrix
fscanf(archivo,"%f\t%f\t%f\t%f\t%f\t%f\n",
&M[0][i],&M[1][i],&M[2][i],&M[3][i],&M[4][i],&M[5][i]);
i++;
}
tam=i;
fclose (archivo); //closes the file
return M;
}
我需要的是声明矩阵的正确方法。
P.S。我记录了代码中的主线,以防它可以帮助需要类似东西的人。
欢迎任何更正。
更新: 应用了评论中提出的一些更改,并且工作得更好,这是我为该功能提供的新代码
float **carga_archivo(char *nombre_archivo)
{
int i=0;
float P[300][6];
FILE *archivo;
archivo=fopen(nombre_archivo,"r");
while(!feof(archivo))
{
i++;
//this was just so the feof function could browse row per row
//instead of character per character
scanf("%f\t%f\t%f\t%f\t%f\t%f\n",
&P[0][i],&P[1][i],&P[2][i],&P[3][i],&P[4][i],&P[5][i]);
printf("%i\n",i);
}
tam=i;
printf("%i",tam);
int filas = 6;
int columnas = tam;
float **M;
M = (float **)malloc(filas*sizeof(float*));
for (i=0;i<filas;i++)
M[i] = (float*)malloc(columnas*sizeof(float));
for (i = 0; i < columnas; ++i)
fscanf(archivo,"%f\t%f\t%f\t%f\t%f\t%f\n",
&M[0][i],&M[1][i],&M[2][i],&M[3][i],&M[4][i],&M[5][i]);
fclose (archivo);
return M;
}
新问题是当函数被调用时,程序实际编译,但是当它运行并且函数被调用时程序崩溃并停止。 这是调用该函数的代码部分。
int main()
{
int i,j;
char *nombre_archivo="Agua_Vapor.txt";
float **agua_vapor=carga_archivo(nombre_archivo);
for (i = 0; i < 6; i++)
{
for (j = 0; i < tam; i++)
printf("%f ", agua_vapor[i][j]);
printf("\n");
}
return 0;
}
答案 0 :(得分:2)
您的程序有未定义的行为,因为您正在填充由未初始化的指针引用的内存。
因为您知道总有6列,所以一种简单的方法是将矩阵存储为行主要而不是列主要(您的示例是列主要)。这意味着您可以将矩阵数据存储为一大块内存,并在必要时使用realloc
。您可能也希望为此创建一个简单的结构。
struct matrix {
int rows, cols;
float ** data;
};
然后动态创建它。
struct matrix * matrix_alloc( int rows, int cols )
{
int i;
struct matrix * m = malloc(sizeof(struct matrix));
m->rows = rows;
m->cols = cols;
m->data = malloc(rows * sizeof(float*));
m->data[0] = malloc(rows * cols * sizeof(float));
for( i = 1; i < rows; i++ ) {
m->data[i] = m->data[i-1] + cols;
}
return m;
}
void matrix_free( struct matrix * m )
{
free( m->data[0] );
free( m->data );
free( m );
}
现在,当您决定需要为更多行添加存储时:
void matrix_set_row_dimension( struct matrix * m, int rows )
{
float **new_index, *new_block;
new_index = realloc(m->data, rows * sizeof(float**));
new_block = realloc(m->data[0], rows * m->cols * sizeof(float));
if( new_index && new_block )
{
int i = m->rows;
m->rows = rows;
m->data = new_index;
/* if block address changed, prepare to reindex entire block */
if( m->data[0] != new_block )
{
m->data[0] = new_block;
i = 1;
}
/* reindex */
for( ; i < rows; i++ ) {
m->data[i] = m->data[i-1] + cols;
}
}
}
所以,现在填充矩阵......
struct matrix * m = matrix_alloc( 10, 6 ); /* Start with 10 rows */
int row = 0;
while( 1 ) {
/* Double matrix row count if not large enough */
if( row == m->rows )
{
matrix_set_row_dimension( m, m->rows * 2 );
/* Check for error here */
}
/* Now the matrix has enough storage to continue adding */
m->data[row][0] = 42;
m->data[row][1] = 42;
m->data[row][2] = 42;
m->data[row][3] = 42;
m->data[row][4] = 42;
m->data[row][5] = 42;
row++;
}