从C中的函数返回矩阵

时间:2016-12-06 01:58:13

标签: c matrix

我正在制作一个程序,我必须不断地在函数中使用矩阵,这是众多函数中的一个,这个函数应该打开一个外部文件,这是一个数据集,其中数据是用表格,它打开文件并将数据保存在矩阵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;
}

1 个答案:

答案 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++;     
}